简体   繁体   中英

MySQL how to repeat query for every value in a column

This is an example of the tables and the columns used:

t_values:
╔════════════╦═══════════════╗
║ Serial     ║ Date          ║
╠════════════╬═══════════════╣
║ 1234214    ║ 2010.11.01... ║
╠════════════╬═══════════════╣
║ ABC9123213 ║ 2001.01.01... ║
╠════════════╬═══════════════╣
║ ...        ║ ...           ║
╚════════════╩═══════════════╝

t_devices:
╔════════════╦══════╗
║ Serial     ║ Type ║
╠════════════╬══════╣
║ 1234214    ║ 2    ║
╠════════════╬══════╣
║ ABC9123213 ║ 13   ║
╠════════════╬══════╣
║ ...        ║ ...  ║
╚════════════╩══════╝

I have this query to get count values grouped by weaks, but also separated by the Type field:

SELECT CONCAT(YEAR(V.Date), '/', WEEK(V.Date)) AS Yearweek, COUNT(*) AS QTY, D.TypeID
FROM 
t_values    AS V
JOIN 
t_devices   AS D 
ON V.Serial = D.Serial
WHERE D.TypeID = 1 --This is what I change manually
GROUP BY Yearweek
ORDER BY YEAR(V.Date) ASC, WEEK(V.Date) ASC
;

This D.TypeID column has about 13 distinct values so I need to manually change it for every value and re-run the query.

But clearly this is an anti-DRY approach. Since I'm new with MySQL I have the basic ideas about writing these kind of " static " queries but I have no particular experience or idea about the proper solutions for some more dynamic conditions.

I know of the possibility of stored procedures. Is it something that I should try to use exactly for problems like this, or is there some simpler, built-in tool to iterate this query with the different distinct values of a choosen column instead?

Edit: I was asked to clarify how would I even need the results, since I could just group by the Yearkweek column as well and leave the WHERE part. Only that it would just give me one big table with the Yearweek-TypeID pairs.

I need the query I've posted with their actual own separate Type results, maybe ran dynamically after one another. And maybe I'll call this query with another language or implement it with an ORM and save the results into dataframes or excels every time on query is done.

So I am just not sure which direction is the preferred one. Should I use a variable and loop that with the language I run the SQL query with or create the procedure with native MySQL beforehand an call that.

You can get all the data in one result this way:

SELECT D.TypeID,
       CONCAT(YEAR(V.Date), '/',
       WEEK(V.Date)) AS Yearweek, COUNT(*) AS QTY, D.TypeID
FROM 
t_values    AS V
JOIN 
t_devices   AS D 
ON V.Serial = D.Serial
GROUP BY D.TypeID, Yearweek
ORDER BY D.TypeID,YEAR(V.Date) ASC, WEEK(V.Date) ASC
;

Or you can take input using a bound variable,

SELECT CONCAT(YEAR(V.Date), '/', WEEK(V.Date)) AS Yearweek, COUNT(*) AS QTY, D.TypeID
FROM 
t_values    AS V
JOIN 
t_devices   AS D 
ON V.Serial = D.Serial
WHERE D.TypeID = ?
GROUP BY Yearweek
ORDER BY YEAR(V.Date) ASC, WEEK(V.Date) ASC
;

How you supply the variable is going to depend on what you are using to call SQL.

You can create a stored procedure. The great way to call stored procedures is with a bound variable, but you could pass the argument by generating an SQL string with the argument.

CREATE PROCEDURE type_data
(IN type_in INTEGER)
BEGIN
  SELECT CONCAT(YEAR(V.Date), '/', WEEK(V.Date)) AS Yearweek, COUNT(*) AS QTY, D.TypeID
  FROM 
  t_values    AS V
  JOIN 
  t_devices   AS D 
  ON V.Serial = D.Serial
  WHERE D.TypeID = type_in
  GROUP BY Yearweek
  ORDER BY YEAR(V.Date) ASC, WEEK(V.Date) ASC
END
;

CALL type_data(1);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM