MySQL Dynamic Query Challenge - Помогите, пожалуйста! - PullRequest
0 голосов
/ 26 августа 2010

У меня есть этот запрос:


   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", а не указывать их вручную (см. Мой запрос)

Таким образом, для всех предложений, которые пользователь щелкнул или не щелкнул (столбцы), будут предложены таблицы.

должно быть так: «предложение _» + предложение. ID

Это должно выглядеть следующим образом: (при условии, что в таблице предложений только 2 предложения с идентификаторами 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        |                |

Ответы [ 3 ]

1 голос
/ 26 августа 2010

Такой запрос может стать очень запутанным, очень быстро. Я бы предложил использовать более стандартные запросы для получения ваших данных, а затем обработать эти данные в вашем приложении.

Однако, если есть действительно веская причина для создания динамического запроса, вот один из способов, которым вы можете это сделать - это просто строительные блоки, поэтому вам нужно изменить его в соответствии с вашими требованиями:

Используйте CONCAT и GROUP_CONCAT для построения оператора SELECT для использования в подготовленном операторе :

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;
0 голосов
/ 26 августа 2010

Mike

Вот что он возвращает: посмотри в конце, как его отрезать - странно. Что бы это могло быть?

Я также не понял последнюю часть вашего комментария - Последний блок;

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;

Вот вывод:

ВЫБРАТЬ SUM (ЕСЛИ (OFFER_ID = 178, 1, 0)) AS offer_178, SUM (ЕСЛИ (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 (ЕСЛИ (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 = 2) 43, 1, 0)) AS offer_243, SUM (ЕСЛИ (ВЫКЛЮЧЕНО ИЗ ТРАКАЦИИ;

)
0 голосов
/ 26 августа 2010

Рассматривали ли вы получение списка идентификаторов пользователей и идентификаторов предложений, отсортированных сначала по идентификатору пользователя, а затем по идентификатору предложения? Это та же самая информация, просто организованная немного по-другому, плюс для базы данных было бы намного, намного быстрее, выполнить запрос типа "выберите user_id, offer_id from track".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...