2012-07-04 1 views
1

я таблицу, как этот VB (имя символ (25), количество числовой (6), ret_date дата):SQL подзапросов рассчитывать на нескольких условиях

Name Amount Ret_date 
---- ------ -------- 
abc 500 2011-01-21 
def 200 2011-01-20 
ghi 1000  
xyz 800 2011-01-22 
def 200  
def 400 2011-02-01 
pqr 2100 2011-02-12 
abc 3000  
abc 4100 
xyz 700 2011-01-22 

То, что я хотел это (рассчитывать на основе ret_date для различных имен: общее количество, счетчик обратного, до счетчика):

Name tc rc pc 
abc  3 1 2 
def  3 2 1 
xyz  2 2 0 
ghi  1 0 1 
pqr  1 1 0 

Я попытался следующие запросы, ничего не получалось!

SELECT vb.name, COUNT(*) tc, r.rc, p.pc FROM vb, ; 
(SELECT name, COUNT(*) rc FROM vb WHERE ret_date != {} group BY name) r, ; 
(SELECT name, COUNT(*) pc FROM vb WHERE ret_date = {} group BY name) p ; 
GROUP BY vb.name ORDER BY tc desc 
SELECT vb.name, COUNT(*) tc, r.rc, p.pc FROM vb ; 
    LEFT JOIN (select name, COUNT(*) rc FROM vb WHERE ret_date != {} group BY name) r ON r.name = vb.name ; 
    LEFT JOIN (select name, COUNT(*) pc FROM vb WHERE ret_date = {} group BY name) p ON p.name = vb.name ; 
    GROUP BY vb.name 
SELECT vb.name, COUNT(*) tc, r.rc, p.pc FROM vb ; 
    LEFT JOIN (select r.name, COUNT(*) rc FROM vb r WHERE ret_date != {} group BY name) r ON r.name = vb.name ; 
    LEFT JOIN (select p.name, COUNT(*) pc FROM vb p WHERE ret_date = {} group BY name) p ON p.name = vb.name ; 
    GROUP BY vb.name 

Я был в состоянии получить счетчик с 3-мя отдельными запросами (общее количество, рассчитывать на ret_date = {}, ret_date! = {}), Но не может получить одновременно с помощью одного запроса. Пожалуйста, помогите мне получить желаемый результат. Я новичок в SQL и могу понять основы, но такие вещи, как объединения, подзапросы по-прежнему трудно понять! Было бы полезно, если бы вы могли объяснить, что делает ваш запрос.

Примечание: Я использую MS Visual Foxpro 9.0 (Windows 7). {} - это обозначение, используемое для выражения пустоты для типа даты в Foxpro и ! = не равно оператору.

Большое спасибо.

ответ

3
SELECT name, COUNT(DISTINCT name) as uc, COUNT(*) as tc, SUM(IF(ret_date IS NULL, 0, 1)) as rc, SUM(IF(ret_date IS NOT NULL, 0, 1)) as pc 
FROM vb 
GROUP BY name; 

У меня нет доступа к Foxpro, но это работает в MySQL. Надеюсь, вы сможете настроить его в соответствии с вашими потребностями.

+0

Это сработало отлично! Одна вещь, которую я не получил, выражение ** COUNT (имя DISTINCT) как uc ** дает 1 для всех имен ?! Во всяком случае, я получил то, что хочу. Еще одно сомнение: не можем ли мы получить _pc_ значение как _tc - rc_ ?! Большое спасибо :-) – Ganapathy

+0

Часть COUNT (DISTINCT name) была выбрана, когда я проводил некоторое тестирование запроса. Извини за это. Вы можете удалить имя из выбранного, а также группы, и запрос даст вам те подсчеты, суммированные по всей таблице. В противном случае вы можете получить точное количество уникальных пользователей, просто подсчитав набор результатов из первого запроса. Что касается вычисления pc, вы, безусловно, можете это сделать. Я просто был откровенен, чтобы еще раз взглянуть на такой же счетный трюк. – keelerm

0

У меня нет опыта работы с Foxpro, однако я бы предположил, что COUNT(*) даст ваш общий счет, COUNT(Ret_Date) предоставит вам ваш ожидающий счет (так как он не будет считать нулевые значения). Затем COUNT(*) - COUNT(Ret_Date) (tc - rc) предоставит ваш ожидающий счет. Это может устранить необходимость в подзапросах (если VFP ведет себя как другие СУБД при подсчете).

SELECT Name, COUNT(*) tc, COUNT(Ret_Name) rc, COUNT(*) - COUNT(Ret_Name) pc 
FROM VB 
GROUP BY Name; 
+0

Я бы это проверил. Спасибо за помощь. – Ganapathy