Хитрый запрос MySQL вместо скрипта Python для достижения результата? - PullRequest
4 голосов
/ 15 августа 2011

Прежде чем приступить к написанию скрипта Python, я хочу посмотреть, может ли только MySQL дать результат.

У меня есть список продуктов:

PID Product 
-----------
1   AAA
2   ABC
3   BAC
4   CAB
5   CBA

У меня есть список компаний, заказывающих эти продукты несколько раз:

CID PID
-------
1   1
2   3
1   5
3   2
1   1
2   3 

Желаемый результат:

CID AAA ABC BAC CAB CAB CBA
---------------------------
1   Y                   Y
2           Y
3       Y  

Как бы я это сделал в Python?

  • Создание временной таблицы со столбцами (CID AAA ABC BAC CAB CAB CBA)
  • Запустите 2 цикла и обновите нужную таблицу, когда нужный столбец совпадет.

Просто любопытно посмотреть, существует ли решение только для MySQL.

p.s: Это всего лишь пример, и в действительности проблема состоит из нескольких сотен продуктов и нескольких тысяч компаний. Я создал временную таблицу для 100 продуктов, выполнив транспонирование в Excel, и преобразовал ее в таблицу MySQL.

Ниже приводится подход, к которому я наконец прибегнул. Спасибо за отзыв ребята.

########### Python script to generate the MySQL query ##############

#MySQL Connection String Goes here#

#Generate MySQL 'CASE' logic

cursor = db.cursor()

if __name__ == '__main__':

    cursor.execute("select PID, Product from products")
    productlist = cursor.fetchall()

    for product in productlist:
        print ("max(case when PID = %s then 'Y' else '' end) as `%s`,") % (product[0], product[1])

db.close()

Используйте сгенерированный запрос в формате, предложенном ник.

select cid,
max(case when pid = 1 then 'Y' else '' end) as AAA,
max(case when pid = 2 then 'Y' else '' end) as ABC,
max(case when pid = 3 then 'Y' else '' end) as BAC,
max(case when pid = 4 then 'Y' else '' end) as CAB,
max(case when pid = 5 then 'Y' else '' end) as CBA
from companies
group by cid

Ответы [ 5 ]

3 голосов
/ 15 августа 2011
select cid,
max(case when pid = 1 then 'Y' else '' end) as AAA,
max(case when pid = 2 then 'Y' else '' end) as ABC,
max(case when pid = 3 then 'Y' else '' end) as BAC,
max(case when pid = 4 then 'Y' else '' end) as CAB,
max(case when pid = 5 then 'Y' else '' end) as CBA
from companies
group by cid
2 голосов
/ 15 августа 2011

Другие ответы, кажется, танцуют вокруг того факта, что для большого количества продуктов не существует практического способа сделать это только в MySQL.

См. Ответ на этот вопрос: Транспонирование строк в столбцы в MySQL

Итак, ответ на ваш вопрос, вероятно, таков: напишите сценарий Python.

0 голосов
/ 16 августа 2011

Это объединит все результаты в один столбец вместо 5 (или 100):

SELECT
    o.CID
  , GROUP_CONCAT( CASE WHEN d.dummy IS NOT NULL 
                       THEN ' Y '
                       ELSE '   '
                  END 
                  ORDER BY p.Product
                  SEPARATOR ' '
                ) AS Products
FROM
    ( SELECT DISTINCT 
          CID
      FROM Ordering
    ) AS c
  CROSS JOIN 
    Product p
  LEFT JOIN 
    (SELECT 1 AS dummy) AS d
      ON EXISTS
         ( SELECT *
           FROM Ordering AS o
           WHERE o.PID = p.PID
             AND o.CID = c.CID
         )
GROUP BY c.CID

Если, однако, у вас есть 100 продуктов и 10 000 компаний, это может быть чертовски медленно.

0 голосов
/ 15 августа 2011

Почему у вас есть дубликаты данных?Дважды есть 1 1 и 2 3.

Я не понимаю желания представлять данные таким образом.Если это будет отображаться в вашем интерфейсе, это плохая идея.Придерживайтесь Python Я говорю и делаю это в один цикл: 1) создать таблицу 2) извлечь данные 3) foreach результат в наборе результатов выбора cid, pid ... пометить таблицу как 'Y'

0 голосов
/ 15 августа 2011

Я не уверен в желаемом результате, но довольно просто создать что-то похожее в MySQL, используя usind GROUP BY, что может упростить создание желаемого представления в Python:

SELECT orders.cid, products.product
FROM orders, products
WHERE orders.pid=products.pid
GROUP BY products.product
...