我有这个问题:
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_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 |
跟踪表:
+------------+-------------+------+-----+---------+----------------+
| 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 | |
+------------+-------------+------+-----+---------+----------------+
用户列表表:
+-------------+--------------+------+-----+---------+-------+
| 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 | |
提供表:
+------------------+--------------+------+-----+-------------+----------------+
| 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 | |
答案 0 :(得分:1)
这种查询很快就会变得非常混乱。我建议使用更多标准查询来获取数据,然后在应用程序中处理这些数据。
但是,如果有一个非常好的理由来创建动态查询,这里有一种方法可以做 - 这些只是构建块,所以你需要修改它以满足你的要求:
使用CONCAT和GROUP_CONCAT构建一个SELECT语句,以便在prepared statement中使用:
SELECT CONCAT(
'SELECT',
GROUP_CONCAT(
' SUM(IF(offer_id = ', offer_id,
', 1, 0)) AS offer_', offer_id),
' FROM track;')
INTO @sql
FROM (SELECT DISTINCT offer_id FROM track) AS track;
以上命令创建的内容为:
SELECT @sql;
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| @sql |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| SELECT SUM(IF(offer_id = 1, 1, 0)) AS offer_1, SUM(IF(offer_id = 2, 1, 0)) AS offer_2, SUM(IF(offer_id = 3, 1, 0)) AS offer_3, SUM(IF(offer_id = 4, 1, 0)) AS offer_4 FROM track; |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
从动态SQL创建并执行预准备语句:
PREPARE stmt FROM @sql;
EXECUTE stmt;
+---------+---------+---------+---------+
| offer_1 | offer_2 | offer_3 | offer_4 |
+---------+---------+---------+---------+
| 3 | 2 | 1 | 1 |
+---------+---------+---------+---------+
DEALLOCATE PREPARE stmt;
答案 1 :(得分:0)
您是否考虑过获取用户ID和商品ID的列表,首先按用户ID排序,然后按商品ID排序?这是相同的信息,只是略有不同的组织,而且数据库执行像“select user_id,offer_id from track”这样的查询要快得多。
答案 2 :(得分:0)
麦克,
它返回的内容:最后看到它的切断方式 - 很奇怪。它可能是什么?
我也不明白你评论的最后部分 - 最后一个块;
Create and execute a prepared statement from the dynamic SQL:
PREPARE stmt FROM @sql;
EXECUTE stmt;
+---------+---------+---------+---------+
| offer_1 | offer_2 | offer_3 | offer_4 |
+---------+---------+---------+---------+
| 3 | 2 | 1 | 1 |
+---------+---------+---------+---------+
DEALLOCATE PREPARE stmt;
以下是新查询:
SELECT CONCAT(
'SELECT',
GROUP_CONCAT(
' SUM(IF(OFFER_ID = ', offer_id,
', 1, 0)) AS offer_', offer_id),
' FROM track;')
INTO @sql
FROM (SELECT DISTINCT ID as OFFER_ID from offer where `STATUS`=1) AS track;
select @sql;
这是输出:
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(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;