MySQL 动态查询挑战 - 请帮忙!
我有这个查询:
SELECT
userlist.USERID,
(case when (sum( CASE WHEN track.OFFER_ID = 221 THEN 1 ELSE 0 END) > 1) then 1 else 0 end) offer_211
FROM
userlist
INNER JOIN track ON userlist.USERID = track.USERID
group by
userid
这是输出:
+------------+----------
| USERID | offer_211 |
+------------+----------
| 1657487706 | 0 |
| 1238439394 | 0 |
| 1238427171 | 1 |
| 1248431441 | 0 |
| 1248464345 | 1 |
这个查询的目的:
有一个用户表、报价表和跟踪表。轨迹表包含用户表中的所有点击。我想创建一个像上面这样的视图,它将向我显示用户对所有优惠的所有点击。如果用户点击某个优惠,它将在该优惠列下显示“1”,否则将显示“0”。所有记录均来自轨迹表。
这是我需要帮助的内容: 我希望能够从“offer”表动态创建列“offer_211”,而不是手动指定它们。(请参阅我的查询)
因此,对于用户单击或未单击的所有优惠(列)将来自提供表。
它应该是这样的:“offer_”+offer.ID
它应该看起来像这样:(假设报价表中只有 2 个报价,ID 为 211, 212)
报价表中可能有 100 个报价,所以此视图应该有相同数量的动态列。
| USERID | offer_211 | offer_212 |
+------------+----------+-------------
| 1657487706 | 0 | 1 |
| 1238439394 | 0 | 0 |
| 1238427171 | 1 | 0 |
| 1248431441 | 0 | 1 |
| 1248464345 | 1 | 0 |
track 表:
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| ID | int(22) | NO | PRI | NULL | auto_increment |
| OFFER_ID | int(22) | YES | MUL | NULL | |
| USERID | int(22) | YES | MUL | NULL | |
+------------+-------------+------+-----+---------+----------------+
userlist 表:
+-------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| USERID | int(22) | NO | PRI | 0 | |
| EMAIL | varchar(200) | YES | | NULL | |
| FIRSTNAME | varchar(100) | YES | | NULL | |
| LASTNAME | varchar(100) | YES | | NULL | |
offer 表:
+------------------+--------------+------+-----+-------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+-------------+----------------+
| ID | int(11) | NO | PRI | NULL | auto_increment |
| NAME | varchar(100) | YES | | NULL | |
| DESCRIPTION | text | YES | | NULL | |
| URL | text | YES | | NULL | |
I have this query:
SELECT
userlist.USERID,
(case when (sum( CASE WHEN track.OFFER_ID = 221 THEN 1 ELSE 0 END) > 1) then 1 else 0 end) offer_211
FROM
userlist
INNER JOIN track ON userlist.USERID = track.USERID
group by
userid
This is the output:
+------------+----------
| USERID | offer_211 |
+------------+----------
| 1657487706 | 0 |
| 1238439394 | 0 |
| 1238427171 | 1 |
| 1248431441 | 0 |
| 1248464345 | 1 |
Purpose of this query:
There is a user table, offer table and track table. Track table contains all the clicks from user table. I want to create a view like above, which will show me all the clicks from users for all the offers. If the user clicked on a certain offer it will display '1' under that offer column, if not it will display '0'. All the records are coming from track table.
Here is what i need help with:
I want to be able to dynamically create columns "offer_211" from "offer" table instead of specifing them manually.(see my query)
So, for all the offers that a user clicked, or not clicked (columns) would be from offer the table.
it should be like this: "offer_"+offer.ID
It should look like this: (assuming there are only 2 offers in the offer table with ids 211, 212)
There could be 100's of offers in the offer table so there should be the same amount of dynamic columns for this view.
| USERID | offer_211 | offer_212 |
+------------+----------+-------------
| 1657487706 | 0 | 1 |
| 1238439394 | 0 | 0 |
| 1238427171 | 1 | 0 |
| 1248431441 | 0 | 1 |
| 1248464345 | 1 | 0 |
track Table:
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| ID | int(22) | NO | PRI | NULL | auto_increment |
| OFFER_ID | int(22) | YES | MUL | NULL | |
| USERID | int(22) | YES | MUL | NULL | |
+------------+-------------+------+-----+---------+----------------+
userlist Table:
+-------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| USERID | int(22) | NO | PRI | 0 | |
| EMAIL | varchar(200) | YES | | NULL | |
| FIRSTNAME | varchar(100) | YES | | NULL | |
| LASTNAME | varchar(100) | YES | | NULL | |
offer Table:
+------------------+--------------+------+-----+-------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+-------------+----------------+
| ID | int(11) | NO | PRI | NULL | auto_increment |
| NAME | varchar(100) | YES | | NULL | |
| DESCRIPTION | text | YES | | NULL | |
| URL | text | YES | | NULL | |
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这种查询很快就会变得非常混乱。我建议使用更标准的查询来获取数据,然后在应用程序中处理该数据。
但是,如果确实有充分的理由创建动态查询,则可以采用以下一种方法 - 这些只是构建块,因此您需要对其进行修改以满足您的要求:
使用 CONCAT 和 GROUP_CONCAT 构建用于 准备好的语句:
以下是上述命令创建的内容:
创建并执行准备好的语句动态SQL:
This sort of query can become very messy, very quickly. I would suggest using more standard queries to obtain your data, then process that data in your application.
However, if there is a really good reason for creating a dynamic query, here's one way you can do it—these are just building blocks, so you'll need to modify it to suit your requirements:
Use CONCAT and GROUP_CONCAT to build a SELECT statement for use in a prepared statement:
Here's what the above command creates:
Create and execute a prepared statement from the dynamic SQL:
您是否考虑过获取用户 ID 和优惠 ID 的列表,首先按用户 ID 排序,然后按优惠 ID 排序?这是相同的信息,只是组织方式略有不同,而且数据库执行“select user_id, Offer_id from track”之类的查询会快得多。
Have you considered getting a list of user IDs and offer IDs, sorted first by user ID and next by offer ID? It's the same information, just organized slightly differently, plus it'd be much, much faster for the database to execute a query like "select user_id, offer_id from track".
迈克,
这是它返回的内容:看看最后它是如何被切断的 - 奇怪。可能是什么?
我也不明白你评论的最后一部分 - 最后一块;
这是新查询:
这是输出:
SELECT SUM(IF(OFFER_ID = 178, 1, 0)) AS Offer_178, SUM(IF(OFFER_ID = 234, 1, 0)) AS Offer_234, SUM(IF(OFFER_ID = 206, 1, 0)) AS Offer_206, SUM(IF(OFFER_ID = 213, 1, 0)) AS Offer_213, SUM(IF(OFFER_ID = 229, 1, 0)) AS Offer_229, SUM(IF(OFFER_ID = 220, 1, 0)) AS Offer_220, SUM(IF(OFFER_ID = 221, 1, 0)) AS Offer_221, SUM(IF(OFFER_ID = 222, 1, 0)) AS Offer_222, SUM(IF(OFFER_ID = 225, 1, 0)) AS Offer_225, SUM(IF(OFFER_ID = 226, 1, 0)) AS Offer_226, SUM(IF(OFFER_ID = 257, 1, 0)) AS Offer_257, SUM(IF(OFFER_ID = 259, 1, 0) ) AS Offer_259, SUM(IF(OFFER_ID = 258, 1, 0)) AS Offer_258, SUM(IF(OFFER_ID = 260, 1, 0)) AS Offer_260, SUM(IF(OFFER_ID = 228, 1, 0)) AS Offer_228, SUM(IF(OFFER_ID = 230, 1, 0)) AS Offer_230, SUM(IF(OFFER_ID = 232, 1, 0)) AS Offer_232, SUM(IF(OFFER_ID = 233, 1, 0)) AS Offer_233, SUM(IF(OFFER_ID = 239, 1, 0)) AS Offer_239, SUM(IF(OFFER_ID = 240, 1, 0)) AS Offer_240, SUM(IF(OFFER_ID = 241, 1, 0)) AS Offer_241, SUM( IF(OFFER_ID = 242, 1, 0)) AS Offer_242, SUM(IF(OFFER_ID = 243, 1, 0)) AS Offer_243, SUM(IF(OFFE FROM track;)
Mike,
Here what it returns: See at the end how its cut off - weird. What could it be?
I also didn't understand the last part of your comment - Last block;
Here is the new query:
Here is the output:
SELECT SUM(IF(OFFER_ID = 178, 1, 0)) AS offer_178, SUM(IF(OFFER_ID = 234, 1, 0)) AS offer_234, SUM(IF(OFFER_ID = 206, 1, 0)) AS offer_206, SUM(IF(OFFER_ID = 213, 1, 0)) AS offer_213, SUM(IF(OFFER_ID = 229, 1, 0)) AS offer_229, SUM(IF(OFFER_ID = 220, 1, 0)) AS offer_220, SUM(IF(OFFER_ID = 221, 1, 0)) AS offer_221, SUM(IF(OFFER_ID = 222, 1, 0)) AS offer_222, SUM(IF(OFFER_ID = 225, 1, 0)) AS offer_225, SUM(IF(OFFER_ID = 226, 1, 0)) AS offer_226, SUM(IF(OFFER_ID = 257, 1, 0)) AS offer_257, SUM(IF(OFFER_ID = 259, 1, 0)) AS offer_259, SUM(IF(OFFER_ID = 258, 1, 0)) AS offer_258, SUM(IF(OFFER_ID = 260, 1, 0)) AS offer_260, SUM(IF(OFFER_ID = 228, 1, 0)) AS offer_228, SUM(IF(OFFER_ID = 230, 1, 0)) AS offer_230, SUM(IF(OFFER_ID = 232, 1, 0)) AS offer_232, SUM(IF(OFFER_ID = 233, 1, 0)) AS offer_233, SUM(IF(OFFER_ID = 239, 1, 0)) AS offer_239, SUM(IF(OFFER_ID = 240, 1, 0)) AS offer_240, SUM(IF(OFFER_ID = 241, 1, 0)) AS offer_241, SUM(IF(OFFER_ID = 242, 1, 0)) AS offer_242, SUM(IF(OFFER_ID = 243, 1, 0)) AS offer_243, SUM(IF(OFFE FROM track;