Все строки, содержащие не менее # соответствующих строк - PullRequest
2 голосов
/ 02 января 2012

Скажем, у нас есть такая таблица:

**tablename**
ID     Name      Size      Date   AtStore1  AtStore2
 1    Apple    Medium  20120101                  Yes
 2     Pear    Medium  20111231        Yes       Yes
 3    Lemon     Small  20111231        Yes       Yes
 4   Orange     Small  20111231        Yes          
 5   Carrot    Medium  20111231        Yes          
 6   Potato     Small  20111231        Yes          
 7   Celery     Large  20111231                  Yes
 8    Onion    Medium  20111231                     
 9   Tomato    Medium  20111231                     
 10   Apple    Medium  20111231                     
 12    Pear    Medium  20111230        Yes       Yes
 13   Lemon     Small  20111230        Yes       
 14  Orange     Small  20111230                  Yes
 15  Carrot    Medium  20111230                  Yes
 16  Potato     Small  20111230           
 17  Celery     Large  20111229                     
 18   Onion    Medium  20111229                  Yes
 19  Tomato    Medium  20111229                     

Можем ли мы построить эффективный запрос, который получает ВСЕ данные на строку, где:

  • «Да» в строках AtStore1, где в этот день в AtStore1 есть как минимум 4 «Да», в тот же день
    ИЛИ (включительно)
  • В магазине AtStore2 есть "Да"

Также приемлемо, если удовлетворяется только первый параметр, то есть прямой поиск строк. Я, вероятно, могу написать скрипт для AtStore2 с PHP, если это необходимо. Все мои попытки потерпели неудачу; мои попытки эффективно написать вопрос в Google тоже не принесли результатов.

(Ответы, разбивающие вещи на разные части кода в PHP, тоже хороши, я просто хочу что-то достаточно эффективное.)

В этом примере таблицы это ожидаемые строки:

ID     Name      Size      Date   AtStore1  AtStore2
 1    Apple    Medium  20120101                  Yes
 2     Pear    Medium  20111231        Yes       Yes
 3    Lemon     Small  20111231        Yes       Yes
 4   Orange     Small  20111231        Yes          
 5   Carrot    Medium  20111231        Yes          
 6   Potato     Small  20111231        Yes          
 7   Celery     Large  20111231                  Yes
12     Pear    Medium  20111230        Yes       Yes
14   Orange     Small  20111230                  Yes
15   Carrot    Medium  20111230                  Yes
18    Onion    Medium  20111229                  Yes

Как видите

  • 1 января 2012
    -Нет Йесес в магазине1
    -AtStore2 имеет Да, поэтому строка возвращается
  • 31 декабря
    -5 Yeses в AtStore1, поэтому они возвращаются (AtStore2 Yeses в ID 2 и 3 также было бы достаточно)
    -Также есть ID 7, так как есть в AtStore2
  • Остальные возвращенные строки были только из-за Yeses в AtStore2

Ответы [ 2 ]

1 голос
/ 02 января 2012

Попробуйте это:

select t.* 
from tablename t
join (
    select date
    from tablename
    where AtStore1='yes'
    group by date
    having count(*) >= 4
) ta on t.date = ta.date and t.AtStore1 = 'yes'
union
select *
from tablename
where AtStore2 = 'yes'

Результат:

ID  Name    Size    Date    AtStore1    AtStore2
1   Apple   Medium  2012-01-01 00:00:00.000 NULL    Yes
2   Pear    Medium  2011-12-31 00:00:00.000 Yes Yes
3   Lemon   Small   2011-12-31 00:00:00.000 Yes Yes
4   Orange  Small   2011-12-31 00:00:00.000 Yes NULL
5   Carrot  Medium  2011-12-31 00:00:00.000 Yes NULL
6   Potato  Small   2011-12-31 00:00:00.000 Yes NULL
7   Celery  Large   2011-12-31 00:00:00.000 NULL    Yes
12  Pear    Medium  2011-12-30 00:00:00.000 Yes Yes
14  Orange  Small   2011-12-30 00:00:00.000 NULL    Yes
15  Carrot  Medium  2011-12-30 00:00:00.000 NULL    Yes
18  Onion   Medium  2011-12-29 00:00:00.000 NULL    Yes

В этом случае нулевые значения намеренно исключаются из совокупности.

Я не уверен, что and t.AtStore1 = 'yes' в ta on t.date = ta.date and t.AtStore1 = 'yes' удалите его, если вы хотите, чтобы все строки имели определенный день, не заботясь о том, имеет ли оно значение yes в столбце AtStore1.

Добавлена ​​

Ответ на вопрос из комментариев, но это быстрый и, вероятно, грязный способ сделать это (нехватка времени):

select t3.*, t4.qty from tablename t3
join (
    select id, max(qty) as qty from (
        select t.id, ta.qty
        from tablename t
        join (
            select date, count(*) as qty
            from tablename
            where AtStore1='yes'
            group by date
            having count(*) >= 4
        ) ta on t.date = ta.date and t.AtStore1 = 'yes'
        union
        select id, 0 as src
        from tablename
        where AtStore2 = 'yes'
    ) t2
    group by t2.id
) t4 on t3.id = t4.id

Результат:

ID  Name    Size    Date    AtStore1    AtStore2    qty
1   Apple   Medium  2012-01-01 00:00:00.000 NULL    Yes 0
2   Pear    Medium  2011-12-31 00:00:00.000 Yes Yes 5
3   Lemon   Small   2011-12-31 00:00:00.000 Yes Yes 5
4   Orange  Small   2011-12-31 00:00:00.000 Yes NULL    5
5   Carrot  Medium  2011-12-31 00:00:00.000 Yes NULL    5
6   Potato  Small   2011-12-31 00:00:00.000 Yes NULL    5
7   Celery  Large   2011-12-31 00:00:00.000 NULL    Yes 0
12  Pear    Medium  2011-12-30 00:00:00.000 Yes Yes 0
14  Orange  Small   2011-12-30 00:00:00.000 NULL    Yes 0
15  Carrot  Medium  2011-12-30 00:00:00.000 NULL    Yes 0
18  Onion   Medium  2011-12-29 00:00:00.000 NULL    Yes 0
0 голосов
/ 02 января 2012

Это должно быть примерно так:

SELECT * FROM t1 WHERE ID IN (
    SELECT Id FROM t1 WHERE AtStore2 != 'Yes' AND Date IN (
        SELECT Date FROM t1 WHERE AtStore1 = 'Yes' GROUP BY Date
        HAVING COUNT(Date) >= 4
))
UNION ALL
SELECT * FROM t1 WHERE AtStore2 = 'Yes'

"ID"; "name"; "size"; "Date"; "Atstore1"; "Atstore2" "1"; "Apple";"Medium"; "20120101"; ""; "Yes" "2"; "Pear"; "Medium"; "20111231"; "Yes"; "Yes" "3"; "Lemon"; "Small"; "20111231 ";" Да ";" Да "" 4 ";" Оранжевый ";" Маленький ";" 20111231 ";" Да ";" "" 5 ";" Морковь ";" Средний ";" 20111231 ";" Да";" "" 6 ";" Картофель ";" Маленький ";" 20111231 ";" Да ";" "" 7 ";" Сельдерей ";" Большой ";" 20111231 ";" ";" Да "" 8";" Лук ";" Средний ";" 20111231 ";" ";" "" 9 ";" Помидор ";" Средний ";" 20111231 ";" ";" "" 10 ";" Яблоко ";" Средний "";" 20111231 ";" ";" "12"; "Груша"; "Средний"; "20111230"; "Да"; "Да" "14"; "Оранжевый"; "Маленький"; "20111230";""; "Да" "15"; "Морковь"; "Средний"; "20111230"; ""; "Да" "18"; "Лук"; "Средний"; "20111229"; ""; "Да"

...