2014-10-29 2 views
1

Мне нужно написать sql-скрипт, который используется для вычисления оставшихся точек клиента после выкупа в начале каждого месяца. Но я не очень уверен в различии между SQL-запросом и SQL. Я написал два запроса, чтобы вычислить полученные и потраченные очки. Для общих заработанных очков:Как сделать функцию вычитания в sql-скрипте

select Tbl_member.member_id,sum(points_earned) 
    from Tbl_member, Tbl_member_participation 
    where tbl_member_participation.member_id = Tbl_member.member_id 
    group by Tbl_member.member_id, 

и точек Потрачено:

select Tbl_member.member_id,sum(points_redeemed) 
    from Tbl_member, Tbl_member_redemption 
    where tbl_member_redemption.member_id = Tbl_member.member_id 
    group by Tbl_member.member_id 

Я хочу, чтобы вычесть потраченные очки от заработанных очков, но я не знаю, как объединить их в signle выхода SQL скрипт. И как сделать этот запуск за каждый месяц.

+0

Pure SQL или базы данных? нет переднего конца? – Edrich

+0

чистый sql, без переднего конца ~ – xiaopassion

+0

Я считаю, что @Edirich хочет, чтобы вы указали, используете ли вы MySQL, Oracle, SQL Server и т. Д. –

ответ

1

Попробуйте

SELECT Tbl_member.member_id, 
     Sum(points_earned) - Sum(points_redeemed) Remaining_points 
FROM Tbl_member 
     JOIN Tbl_member_participation 
     ON tbl_member_participation.member_id = Tbl_member.member_id 
     JOIN Tbl_member_redemption 
     ON tbl_member_redemption.member_id = Tbl_member.member_id 
GROUP BY Tbl_member.member_id, 
      Datepart(mm, datecol), 
      Datepart(yyyy, datecol) 
+0

А где таблица 'Tbl_member_redemption'? –

+0

ya пропустил его и добавил –

+0

А что, если клиент не выкупил какие-либо очки и только заработал очки? –

1

Вы можете просто использовать функцию UNION для объединения двух результатов запроса. Этот запрос не проверен, но это способ, которым вы можете просто играть с двумя запросами с помощью UNION.

SELECT 
    member_id, 
    SUM(points_earned) - SUM(points_redeemed) 
FROM 
(
    SELECT 
     Tbl_member.member_id, 
     sum(points_earned) points_earned, 
     0 AS points_redeemed 
    FROM 
     Tbl_member, 
     Tbl_member_participation 
    WHERE 
    tbl_member_participation.member_id = Tbl_member.member_id 
    GROUP BY 
    Tbl_member.member_id 


    UNION ALL 

    select 
     Tbl_member.member_id, 
     0 AS points_earned, 
     sum(points_redeemed) points_redeemed 
    from 
     Tbl_member, Tbl_member_redemption 
    where 
     tbl_member_redemption.member_id = Tbl_member.member_id 
    group by 
     Tbl_member.member_id 

) as 
a 
GROUP BY 
member_id 
+0

@xiaopassion Пожалуйста, ответьте мне, если эти вопросы дают какие-либо ошибки –

+0

Спасибо, но как убедиться, что этот скрипт может работать для записи за каждый месяц? и зачем «0 AS points_redeemed»? – xiaopassion

+0

Coz вам нужно одинаковое количество столбцов в обоих запросах, тогда только объединение будет работать, поэтому я взял 0 как points_redeemed.for дальнейшая ссылка http://stackoverflow.com/questions/49925/what-is-the-difference-between -union-and-union-all –

1

Вы делаете CROSS JOIN, которые не то, что вы собираетесь (from Tbl_member, Tbl_member_participation). Вместо этого используйте LEFT JOIN или INNER JOIN.

SQL Script может содержать несколько запросов и другие команды типа FOR и т. Д. И может содержать также инструкции GO. С вашей точки зрения это не очень важно.

SELECT m.member_id, SUM(mr.points_redeemed), SUM (mp.points_earned), 
     ISNULL(SUM(mp.points_earned),0) - ISNULL(SUM(mr.points_redeemed),0) as Result 
    FROM Tbl_member m 
    LEFT JOIN Tbl_member_redemption mr ON mr.member_id = m.member_id 
    LEFT JOIN Tbl_member_participation mp ON mp.member_id = m.member_id 
    GROUP BY m.member_id 

Вы можете достичь своей цели одним запросом. Если вы хотите получить результаты для отдельных месяцев, просто добавить критерии к вашей GROUP BY, как это:

GROUP BY m.member_id, MONTH(nameOfDateColumn), YEAR(nameOfDateColumn) 
+0

спасибо! Я попробую это. – xiaopassion

1

если вы не обеспокоены тем, что запрос должен показывать строки для всех членов, то вы можете удалить присоединиться таблицы члена как

SELECT p.member_id, 
     Sum(points_earned), 
     Sum(points_redeemed), 
     Sum(CASE 
      WHEN points_earned IS NULL THEN 0 
      ELSE points_earned 
      END) - Sum(CASE 
         WHEN points_redeemed IS NULL THEN 0 
         ELSE points_redeemed 
         END) AS diff 
FROM Tbl_member_participation p 
     LEFT OUTER JOIN tbl_member_redemption r 
        ON p.member_id = r.member_id 
GROUP BY p.member_id 

иначе использовать это:

SELECT m.member_id, 
     Sum(points_earned), 
     Sum(points_redeemed), 
     Sum(CASE 
      WHEN points_earned IS NULL THEN 0 
      ELSE points_earned 
      END) - Sum(CASE 
         WHEN points_redeemed IS NULL THEN 0 
         ELSE points_redeemed 
         END) AS diff 
FROM Tbl_member m 
     LEFT OUTER JOIN Tbl_member_participation p 
        ON m.member_id = p.member_id 
     LEFT OUTER JOIN tbl_member_redemption r 
        ON m.member_id = r.member_id 
GROUP BY m.member_id ; 

и если вы хотите, чтобы найти разницу месяц мудр тогда

SELECT m.member_id,datepart(mm,p.earndate),datepart(yyyy,p.earndate), 
     Sum(points_earned), 
     Sum(points_redeemed), 
     Sum(CASE 
      WHEN points_earned IS NULL THEN 0 
      ELSE points_earned 
      END) - Sum(CASE 
         WHEN points_redeemed IS NULL THEN 0 
         ELSE points_redeemed 
         END) AS diff 
FROM Tbl_member m 
     LEFT OUTER JOIN Tbl_member_participation p 
        ON m.member_id = p.member_id 
     LEFT OUTER JOIN tbl_member_redemption r 
        ON m.member_id = r.member_id and p.earndate = r.redeemdate 
GROUP BY m.member_id,datepart(mm,p.earndate),datepart(yyyy,p.earndate) 

here является SQL скрипку демо

+0

В SQL Server существует функция ISNULL. Также, когда значения SUM и некоторые из них NULL, вам не нужно использовать ISNULL. –

+0

Благодарим вас за то, что «isnull» можно использовать вместо «case when», «coalesce» - это еще один вариант. Но, предположим, есть point_earned и no point_redeem (в этом месяце), тогда разница будет равна NULL, поэтому я добавил ее, и, возможно, такая ситуация невозможна при использовании фактического БД. это может уточнить: http://sqlfiddle.com/#!3/891e3/3. см. разницу в двух запросах. –

+0

На самом деле вы положили некоторую работу, прорабатывая этот ответ, поэтому +1. Но часть 'ON m.member_id = r.member_id и p.earndate = r.redeemdate' не будет работать так, как должна. –

Смежные вопросы