2015-04-23 6 views
1

Итак, у меня есть 3 стола: [AXprod].[dbo].[RMSPOSINVOICE], [AXPROD].[dbo].[discountcard], [IntegrationProd].[dbo].[POS_KvitoGalva]. И я хочу узнать, когда дисконтная карта использовалась более одного раза в одном изобретении и времени, когда она была использована. Таблица [IntegrationProd].[dbo].[POS_KvitoGalva] имеет эти времена. Я использую этот код, чтобы получить время каждая карта была использована каждый день:Sql select sub query with count

sELECT a.discountcardid,count(a.discountcardid) 
    FROM [AXprod].[dbo].[RMSPOSINVOICE] a 
    inner join [AXPROD].[dbo].[discountcard] b 
    on a.discountcardid = b.discountcardid 
    inner join [IntegrationProd].[dbo].[POS_KvitoGalva] c 
    on a.possalesid = c.id 
    where a.dataareaid = 'ermi' and len(a.discountcardid) > '0' and b.dataareaid = 'ermi' and ('500' = a.inventlocationid) 
and (a.invoicedate >= '2015-04-22 00:00:00.000' and a.invoicedate <= '2015-04-22 00:00:00.000') 
    group by a.discountcardid,a.inventlocationid,a.posnumber 
    having count(a.discountcardid) > '1' 

И я получаю следующий результат:

DISCOUNTCARDID COUNT 
123456   2 
145962   2 

и у меня есть запрос для поиска при использовании каждой карты (дата и время)

SELECT a.discountcardid,a.inventlocationid,a.posnumber,year,month,day,hour,minute,c.id 
FROM [AXprod].[dbo].[RMSPOSINVOICE] a 
    inner join [AXPROD].[dbo].[discountcard] b 
    on a.discountcardid = b.discountcardid 
    inner join [IntegrationProd].[dbo].[POS_KvitoGalva] c 
    on a.possalesid = c.id 
    where a.dataareaid = 'ermi' and len(a.discountcardid) > '0' and b.dataareaid = 'ermi' and ('500' = a.inventlocationid) 
and (a.invoicedate >= '2015-04-22 00:00:00.000' and a.invoicedate <= '2015-04-22 00:00:00.000') 
    group by a.discountcardid,a.inventlocationid,a.posnumber,year,month,day,hour,minute,c.id 
    order by DISCOUNTCARDID 

и я получаю результат:

discountcardid inventlocationid posnumber year month day hour minute id 
123456  500 7 2015 4 22 12 44 6355302 
123456  500 7 2015 4 22 14 24 6355302 
145962  500 7 2015 4 22 13 56 6355302 
145962  500 7 2015 4 22 13 24 6355302 
145555  500 7 2015 4 22 12 11 5465465 

Проблема: Я не хочу, чтобы получить дисконтные карты, которые использовались только один раз, так что я стараюсь это:

SELECT a.discountcardid,a.inventlocationid,a.posnumber,year,month,day,hour,minute,c.id, 
(sELECT count(s.discountcardid) 
    FROM [AXprod].[dbo].[RMSPOSINVOICE] s 
    inner join [AXPROD].[dbo].[discountcard] b 
    on s.discountcardid = b.discountcardid 
    inner join [IntegrationProd].[dbo].[POS_KvitoGalva] c 
    on s.possalesid = c.id 
    where s.dataareaid = 'ermi' and len(s.discountcardid) > '0' and b.dataareaid = 'ermi' and ('500' = s.inventlocationid) 
and (s.invoicedate >= '2015-04-22 00:00:00.000' and s.invoicedate <= '2015-04-22 00:00:00.000') and s.DISCOUNTCARDID = a.DISCOUNTCARDID 
    group by s.discountcardid,s.inventlocationid,s.posnumber 
    having count(a.discountcardid) > '1') 
FROM [AXprod].[dbo].[RMSPOSINVOICE] a 
    inner join [AXPROD].[dbo].[discountcard] b 
    on a.discountcardid = b.discountcardid 
    inner join [IntegrationProd].[dbo].[POS_KvitoGalva] c 
    on a.possalesid = c.id 
    where a.dataareaid = 'ermi' and len(a.discountcardid) > '0' and b.dataareaid = 'ermi' and ('500' = a.inventlocationid) 
and (a.invoicedate >= '2015-04-22 00:00:00.000' and a.invoicedate <= '2015-04-22 00:00:00.000') 
    group by a.discountcardid,a.inventlocationid,a.posnumber,year,month,day,hour,minute,c.id 
    order by DISCOUNTCARDID 

Но я получаю такое же количество значений и NULL в последнем поле во всех колонках. Надеюсь, я ясно дал понять;).

+0

Извините, но эти SQL-инструкции очень трудно читать. Если вы отформатируете их лучше, стало бы легче и вам, и нам найти проблему. – jarlh

ответ

1

Вы должны иметь возможность вызвать запрос один раз и использовать оконную функцию, чтобы получить счет. Я не верю, что вы можете использовать аналитическую функцию в инструкции where, поэтому я добавил дополнительную инструкцию SELECT, чтобы добавить WHERE> 1 для подсчета.

SELECT * 
FROM (SELECT 
    a.discountcardid, 
    a.inventlocationid, 
    a.posnumber, 
    year, 
    month, 
    day, 
    hour, 
    minute, 
    c.id, 
    COUNT(*) OVER (PARTITION BY a.discountcardid, a.inventlocationid, a.posnumber) AS CardCount 
FROM AXprod.dbo.RMSPOSINVOICE a 
JOIN AXprod.dbo.discountcard b 
    ON b.discountcardid = a.discountcardid 
JOIN IntegrationProd.dbo.POS_KvitoGalva c 
    ON c.id = a.possalesid 
WHERE a.dataareaid = 'ermi' 
AND len(a.discountcardid) > '0' 
AND b.dataareaid = 'ermi' 
AND a.inventlocationid = 500 
AND a.invoicedate >= '2015-04-22 00:00:00.000' 
AND a.invoicedate <= '2015-04-22 00:00:00.000' 
) d 
WHERE d.CardCount > 1 
ORDER BY d.discountcardid 
+0

Отлично работает! Можете ли вы объяснить, что означает это утверждение? COUNT (*) OVER (PARTITION by a.discountcardid, a.inventlocationid, a.posnumber) AS CardCount – user2893780

+0

Это оконная функция, которая позволяет использовать для каждой строки функции (MAX, COUNT, SUM и т. Д.), Не используя ГРУППА ПО. Часть, которая находится в PARTITION BY, в основном является GROUP BY в этом случае, но вам не нужно ограничивать остальные выбранные столбцы столбцами GROUP BY, как обычно. В этом примере COUNT подсчитывает количество раз, когда происходит точная группировка discountcardid, inventlocationid и posnumber. simple-talk.com/sql/t-sql-programming/window-functions-in-sql - – hines