Reputation: 131
I have changed my mysql structure and had in the past this query with SUM CASE column keyindex:
SELECT
orders.id,
orders.tool_id,
date(orders.date_placement) AS cdate,
CAST(orders.date_placement AS DATE) AS lala,
positions.id,
positions.optionindex,
positions.keyindex,
tools.id,
tools.tool_name,
tools.tool_number,
SUM(CASE WHEN keyindex=1 THEN 1 ELSE 0 END) AS value1,
SUM(CASE WHEN keyindex=2 THEN 1 ELSE 0 END) AS value2,
SUM(CASE WHEN keyindex=3 THEN 1 ELSE 0 END) AS value3,
SUM(CASE WHEN keyindex=4 THEN 1 ELSE 0 END) AS value4,
DATE_FORMAT(orders.date_placement, '%Y-%m') AS nicecdate
FROM orders
LEFT JOIN tools
ON tools.id=orders.tool_id
LEFT JOIN positions
ON positions.order_id=orders.id
WHERE
tools.id = ?
group by DATE_FORMAT(orders.date_placement, '%Y-%m')
The result of this query looks:
ID | value1 | value2 | value3 | nicedate
1 | 1 | 1 | 4 | 2018-09
2 | 0 | 0 | 1 | 2018-10
3 | 1 | 1 | 1 | 2018-11
4 | 2 | 0 | 0 | 2018-12
That is fine to create some stacked charts in frontend.
But now i added an additional table (repkey) with mapped values (ID1=value1, ID2=value2, ....) and i have added a new column to the first table keyindex2 in addition to keyindex.
ID | keyindex1 | keyindex2 | created
1 | 1 | 27 | 2019-01
2 | 1 | 27 | 2019-01
3 | 2 | 25 | 2019-02
4 | 1 | 27 | 2019-03
5 | 10 | 27 | 2019-04
As result I need every combination from keyindex and keyindex2 based on the corresponding month:
ID | keyindex1 | keyindex2 | Value |count |created
1 | 1 | 27 | value1 value27 | 2 |2019-01
2 | 2 | 25 | value2 value25 | 1 |2019-02
3 | 1 | 27 | value1 value27 | 1 |2019-03
4 | 10 | 27 | value10 value27 | 1 |2019-04
This is what i tried but I have no idea how to count the combination of keyindex and keyindex2 of the corresponding month. The result is also different from that of the old structure so I'm not at all sure if this query does exactly what I want.
SELECT
orders.id,
orders.tool_id,
date(orders.date_placement) AS cdate,
CAST(orders.date_placement AS DATE) AS lala,
positions_list.id AS POSITIONID,
positions_list.order_id AS POSITIONORDERID,
positions_list.keyindex,
positions_list.keyindex2,
RepK.keynr,
RepK.content AS repcontent,
RepK.p_company,
RepK2.keynr,
RepK2.content AS repcontent2,
RepK2.p_company,
COUNT(positions_list.keyindex) AS count,
COUNT(positions_list.keyindex2) AS count2,
DATE_FORMAT(orders.date_placement, '%Y-%m') AS nicecdate
from orders
JOIN tools
ON tools.id=orders.tool_id
JOIN positions_list
ON positions_list.order_id = orders.id
JOIN repkey as RepK
ON RepK.keynr=positions_list.keyindex
AND RepK.p_company=orders.comp_id
JOIN repkey AS RepK2
ON RepK2.keynr=positions_list.keyindex2
WHERE
tools.id =:id
group by DATE_FORMAT(orders.date_placement, '%Y-%m')
BTW: This query is very slow (more then 10 seconds). The Webserver/Database is on nginx with ssd so the issue must be in my query. Are the JOINS the cause?
Upvotes: 1
Views: 39
Reputation: 904
When your needs changed so much that the output and structure of your query isn't the same anymore, it's better to take some distance from the existing code and start the thinking from scrap.
Your need is count the combination of keyindex and keyindex2 of the corresponding month.
We don't know your DB, but this simple need hint strongly in favor of a solution looking like this :
SELECT
positions_list.keyindex,
positions_list.keyindex2,
DATE_FORMAT(orders.date_placement, '%Y-%m') AS nicedate,
COUNT(*) as count,
--...more columns
from orders
JOIN tools
ON tools.id=orders.tool_id
JOIN positions_list
ON positions_list.order_id = orders.id
JOIN repkey as RepK
ON RepK.keynr=positions_list.keyindex
AND RepK.p_company=orders.comp_id
JOIN repkey AS RepK2
ON RepK2.keynr=positions_list.keyindex2
WHERE
tools.id =:id
group by DATE_FORMAT(orders.date_placement, '%Y-%m'),positions_list.keyindex,positions_list.keyindex2
Put the column you want to count separately in the GROUP
and it should do the trick. Now depending on your tables relationship, and what you want to count, the COUNT
may need some work (for example, if you want to count distinct orders, you may need to use COUNT(DISTINCT orders.id)
), but you get the gist.
Also, please take some time to make sure you use JOIN
(=INNER JOIN
) and LEFT JOIN
adequately between each tables, it'll help you get the result you want.
As for the perf, yes JOIN can impact the time your query take but to help you on that we'll need another topic and the details of your DB (most importantly : indexes! you can already check that on your own). There is also a dedicated SE site for DBA.
Upvotes: 1