SQL-запрос с несколькими значениями в одном столбце. Несколько sql запросов в одном
Несколько SELECT COUNT в одном запросе MySQL
В данной небольшой статье речь пойдет о базах данных в частности MySQL, выборке и подсчете. Работая с базами данных, часто требуется совершить подсчет количества строк COUNT() с определенным условием или без, это сделать крайне просто следующим запросом
Запрос вернет значение, с количеством строк в таблице.
Подсчет с условием
Запрос вернет значение, с количеством строк в таблице удовлетворяющих данному условию: var = 1
Для получения нескольких значений подсчета строк с разными условиями, можно поочередно выполнить несколько запросов, например
Но в ряде случаев, такой подход не практичен и не оптимален. По этому актуальным становится организация запроса, с несколькими подзапросами, для получения в одном запросе сразу несколько результатов. Например
Таким образом выполнив всего один запрос к базе данных, мы получаем результат с подсчетом количества строк по нескольким условиям, содержащий несколько значений подсчета, например
c1|c2|c3 -------- 1 |5 |8 |
Недостатком использования подзапросов, в сравнении с несколькими отдельными запросами, можно считать скорость выполнения и нагрузку на базу данных.
Следующий пример запроса, содержащего несколько COUNT в одном запросе MySQL, построен несколько иначе, в нем используются конструкции IF(условие, значение1, значение2), а также суммирование SUM(). Позволяющие произвести отбор данных по заданным критериям в рамках одного запроса, затем суммировать их, и вывести несколько значений в качестве результата.
Как видно из запроса, он построен достаточно лаконично, но скорость его выполнения тоже не порадовала, результат данного запроса будет следующий,
total|c1|c2|c3 -------------- 14 |1 |5 |8 |
Далее я приведу сравнительную статистику скорости выполнения трех вариантов запросов, для выборки нескольких COUNT(). Для тестирования скорости выполнения запросов, было выполнено по 1000 запросов каждого типа, с таблицей содержащей более трех тысяч записей. При этом каждый раз запрос содержал SQL_NO_CACHE для отключение кеширования результатов базой данных.
Скорость выполненияТри отдельных запроса: 0.9 секОдин запрос с подзапросами: 0.95 секОдин запрос с конструкцией IF и SUM: 1.5 сек
Вывод. И так, мы имеет несколько вариантов построения запросов к базе данных MySQL с несколькими COUNT(), первый вариант с отдельными запросами не очень удобен, но имеет наилучший результат по скорости. Второй вариант с подзапросами несколько удобнее, но при этом скорость его выполнение немного ниже. И наконец третий лаконичный вариант запроса с конструкциями IF и SUM, кажущийся самым удобным, имеет самую низкую скорость выполнения, которая почти в два раза ниже первых двух вариантов. По этому, при задаче оптимизации работы БД, я рекомендую использовать второй вариант запроса содержащий подзапросы с COUNT(), во первых его скорость выполнения близка к самому быстрому результату, во вторых такая организация внутри одного запроса достаточно удобна.
Похожие записи
rche.ru
Несколько счетчиков в одном запросе SQL Безопасный SQL
Я пытаюсь получить количество документов в 4 конкретных разделах, используя следующий код:
Таблица «category» имела идентификатор, заголовок и т. Д. В таблице «category_link_section» содержатся ссылки id между категориями, категориями_ид и doc_id.
Если счетчик равен 0 для любого столбца, он отображает 0 в этом столбце. Но если результат не равен 0, он показывает результат умножения всех результатов секции. Поэтому, если бы мои 4 столбца подсчета должны были возвращаться: 1, 2, 0, 3; на самом деле это будет 6, 6, 0, 6;
Если я использую этот следующий код для каждой конкретной категории, я получаю результаты, которые я хочу:
но мне тогда нужно циклически перебирать базу данных каждый раз для каждого раздела.
Поэтому мой вопрос: нужно ли мне перешагнуть и вызвать каждый раздел по очереди, построив таблицу вне SQL, или это можно сделать в одном запросе?
Solutions Collecting From Web of "Несколько счетчиков в одном запросе SQL"
@ Ответ VoteyDisciple находится на правильном пути, но его запрос нуждается в некоторых улучшениях:
SELECT c.id, c.title, SUM(ts1.section_id = 1) AS doc1, SUM(ts1.section_id = 2) AS doc2, SUM(ts1.section_id = 3) AS doc3, SUM(ts1.section_id = 4) AS doc4 FROM category AS c LEFT JOIN category_link_section AS ts1 ON (c.id = ts1.category_id) GROUP BY c.id;Пояснения:
- Выражения IF() являются избыточными, поскольку равенство уже возвращает 1 или 0.
- Возьмите ts1.section_id=1 из условия соединения или вы никогда не получите другие значения section_id .
- Группа только по c.id Я предполагаю, что OP только хочет одну строку для каждой категории и столбцы для подсчета каждого значения section_id для соответствующей категории. Если запрос сгруппирован по c.id, ts1.section_id , тогда будет до четырех строк для каждой категории.
- Перемещайте запятые в списке выбора. Запястья, плавающие в начале строки, выглядят уродливыми. 😉
Возможно, вы захотите попробовать что-то вроде этого:
SELECT category.id , category.title , SUM(IF(ts1.section_id = 1, 1, 0)) AS doc1 , SUM(IF(ts1.section_id = 2, 1, 0)) AS doc2 , SUM(IF(ts1.section_id = 3, 1, 0)) AS doc3 , SUM(IF(ts1.section_id = 4, 1, 0)) AS doc4 FROM category LEFT JOIN category_link_section AS ts1 ON (category.id = ts1.category_id AND ts1.section_id = 1) GROUP BY category.id, ts1.section_idsql.fliplinux.com
подсчитывать несколько столбцов в одном запросе Безопасный SQL
Ребята, у меня есть четыре вопроса:
Запрос №1:
select satisfaction_score,count(satisfaction_score) as Satisfaction_count from j_survey_response where satisfaction_score != 0 group by satisfaction_scoreЗапрос № 2:
select response_score,count(response_score) as response_count from j_survey_response where response_score != 0 group by response_scoreВЫВОД
response_score response_count 1 28 2 8 3 42 4 250 5 980Запрос № 3:
select responder_score,count(responder_score) as responder_count from j_survey_response where responder_score != 0 group by responder_scoreВЫВОД
responder_score responder_count 1 24 2 3 3 30 4 236 5 987Запрос № 4:
select service_score,count(service_score) as service_count from j_survey_response where service_score != 0 group by service_scoreВЫВОД
service_score service_count 1 22 2 2 3 34 4 270 5 966Но мне нужен вывод, как показано ниже.
оценка satisf_count response_count responder_count service_count 1 5 28 24 22 2 8 8 3 2 3 97 42 30 34 4 329 250 236 270 5 859 980 986 966Solutions Collecting From Web of "подсчитывать несколько столбцов в одном запросе"
Вы можете использовать UNION ALL отдельные запросы и применять условную агрегацию в результирующем наборе:
select score, max(case when type = 'satisfaction' then count end) as satisfaction_count, max(case when type = 'response' then count end) as response_count, max(case when type = 'responder' then count end) as responder_count, max(case when type = 'service' then count end) as service_count from ( select satisfaction_score as score, count(satisfaction_score) as count, 'satisfaction' as type from j_survey_response where satisfaction_score != 0 group by satisfaction_score union all select response_score, count(response_score) as count, 'response' as type from j_survey_response where response_score != 0 group by response_score union all select responder_score, count(responder_score) as count, 'responder' as type from j_survey_response where responder_score != 0 group by responder_score union all select service_score, count(service_score) as count, 'service' as type from j_survey_response where service_score != 0 group by service_score) as t group by scoreесли вы используете группу по
select service_score , count(satisfaction_score) as Satisfaction_count, count(response_score) as response_count,count(responder_score) as `responder_count, count(service_score) as service_count from j_survey_response where service_score != 0 and responder_score != 0 and response_score != 0 and satisfaction_score != 0` group by satisfaction_score,response_score,responder_score,service_scoresql.fliplinux.com
sql - SQL-запрос с несколькими значениями в одном столбце
Вам действительно не следует хранить несколько элементов в одном столбце, если ваш SQL когда-либо захочет обрабатывать их по отдельности. "Гимнастика SQL", которую вы должны выполнять в этих случаях, - это как уродливые хаки, так и ухудшение производительности.
Идеальное решение состоит в том, чтобы разделить отдельные элементы на отдельные столбцы и для 3NF переместить эти столбцы в отдельную таблицу в виде строк, если вы действительно хотите сделать это правильно (но детские шаги, вероятно, все в порядке, если вы уверены, что там никогда не будет более двух причин в краткосрочной и среднесрочной перспективе).
Затем ваши запросы будут проще и быстрее.
Однако, если это не вариант, вы можете использовать вышеупомянутую гимнастику SQL, чтобы сделать что-то вроде:
where find ( ',' |fld| ',', ',02,' ) > 0Предполагая, что ваш SQL-диалект имеет функцию поиска строк (find в этом случае, но я думаю charindex для SQLServer).
Это гарантирует, что все подколоны начинаются и начинаются с запятой (запятая плюс поле плюс запятая) и искать конкретное требуемое значение (с запятыми с обеих сторон, чтобы обеспечить полное соответствие столбца).
Если вы не можете контролировать то, что приложение помещает в этот столбец, я бы выбрал решение DBA. Решения DBA определяются как те, которые DBA должен делать, чтобы обойти недостатки своих пользователей: -).
Создайте два новых столбца в этой таблице и создайте триггер insert/update, который заполнит их двумя причинами, которые пользователь помещает в исходный столбец.
Затем запросите эти два новых столбца для определенных значений, а не попытайтесь разделить старый столбец.
Это означает, что затраты на разделение только на вставку/обновление строки, а не на все единичные select`, амортизирующие, что экономически выгодно.
Тем не менее, мой ответ - повторить схему. Это будет лучшим способом в долгосрочной перспективе с точки зрения скорости, читаемых запросов и ремонтопригодности.
qaru.site
SQL-запрос с несколькими значениями в одном столбце Безопасный SQL
Я бил головой по столу, пытаясь понять это. У меня есть таблица, в которой хранятся данные о работе, и причины, по которым работа не завершается. Причины – числовые, 01,02,03 и т. Д. У вас могут быть две причины для ожидающей работы. Если вы выберете две причины, они будут сохранены в том же столбце, разделенном запятой. Это пример из таблицы JOBID :
Существует другая таблица с именем Pending , которая хранит то, что фактически представляют эти значения. 01 = Недостаточно информации, 02 = Недостаточно времени, 03 = Просмотр ожидания. Пример:
То, что я пытаюсь сделать, – это запросить базу данных, чтобы дать мне все номера заданий, пользователей, pendinginfo и ожидающую причину. Я могу вырвать первое значение, но не могу понять, как сделать второе. Каковы мои ограниченные навыки:
То, что я хотел бы увидеть для этого примера, было бы следующим:
Вы действительно не должны хранить несколько элементов в одном столбце, если ваш SQL когда-либо захочет обрабатывать их по отдельности. «Гимнастика SQL», которую вы должны выполнять в этих случаях, – это как уродливые хаки, так и ухудшение производительности.
Идеальное решение состоит в том, чтобы разделить отдельные элементы на отдельные столбцы и для 3NF переместить эти столбцы в отдельную таблицу в виде строк, если вы действительно хотите сделать это правильно (но детские шаги, вероятно, все в порядке, если вы уверены, что никогда не будет более двух причин в краткосрочной и среднесрочной перспективе).
Тогда ваши запросы будут проще и быстрее.
Однако, если это не вариант, вы можете использовать вышеупомянутую гимнастику SQL, чтобы сделать что-то вроде:
where find ( ',' |fld| ',', ',02,' ) > 0предполагая, что ваш SQL-диалект имеет функцию поиска строк ( find в этом случае, но я думаю, что charindex для SQLServer).
Это обеспечит запуск всех подпоследовательностей и начнется с запятой (запятая плюс поле плюс запятая) и найдите конкретное требуемое значение (с запятыми с обеих сторон, чтобы убедиться, что это полное совпадение столбцов).
Если вы не можете контролировать то, что приложение помещает в этот столбец, я бы выбрал решение DBA – решения DBA определяются как те, которые DBA должен делать, чтобы обойти недостатки своих пользователей :-).
Создайте два новых столбца в этой таблице и создайте триггер insert / update, который заполнит их двумя причинами, которые пользователь помещает в исходный столбец.
Затем запросите эти два новых столбца для определенных значений, а не попытайтесь разделить старый столбец.
Это означает, что стоимость расщепления заключается только в вставке / обновлении строки, а не на любом отдельном select`, амортизируя, что экономически эффективно.
Тем не менее, мой ответ – повторить схему. Это будет лучшим способом в долгосрочной перспективе с точки зрения скорости, читаемых запросов и ремонтопригодности.
Надеюсь, вы просто поддерживаете код, и это не новая реализация. Пожалуйста, используйте другой подход, используя таблицу поддержки следующим образом:
JOBS TABLE jobID | userID -------------- 1 | user13 2 | user32 3 | user44 -------------- PENDING TABLE pendingID | pendingText --------------------------- 01 | Not Enough Info 02 | Not Enough Time --------------------------- JOB_PENDING TABLE jobID | pendingID ----------------- 1 | 01 1 | 02 2 | 01 3 | 03 3 | 01 -----------------Вы можете легко запросить эти таблицы с помощью JOIN или подзапросов. Если вам нужна ретро-совместимость на вашем программном обеспечении, вы можете добавить представление для достижения этой цели.
У меня есть таблицы вроде:
Events --------- eventId int eventTypeIds nvarchar(50) ... EventTypes -------------- eventTypeId Description ...Каждое событие может содержать несколько типов событий.
Все, что я делаю, это написать 2 процедуры в моем коде сайта, а не код SQL
-
Одна процедура преобразует значение поля таблицы (eventTypeIds) как «3,4,15,6» в массив ViewState, поэтому я могу использовать его где угодно в коде.
-
Эта процедура делает наоборот, она собирает любые параметры, которые вы проверили, и преобразует их в
Если изменение схемы является опцией (что, вероятно, должно быть), вы не должны реализовывать отношения «многие ко многим», чтобы у вас была таблица мостов между двумя элементами? Таким образом, вы сохраните номер и его формулировку в одной таблице, задания в другом и «причины сбоя рабочих мест» в таблице мостов …
Взгляните на аналогичный вопрос, который я ответил здесь
;WITH Numbers AS ( SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 0)) AS N FROM JobId ), Split AS ( SELECT JOB_NUMBER, USER_ASSIGNED, SUBSTRING(PENDING_INFO, Numbers.N, CHARINDEX(',', PENDING_INFO + ',', Numbers.N) - Numbers.N) AS PENDING_NUM FROM JobId JOIN Numbers ON Numbers.N <= DATALENGTH(PENDING_INFO) + 1 AND SUBSTRING(',' + PENDING_INFO, Numbers.N, 1) = ',' ) SELECT * FROM Split JOIN Pending ON Split.PENDING_NUM = Pending.PENDING_NUMОсновная идея заключается в том, что вы должны умножать каждую строку столько раз, сколько PENDING_NUM . Затем извлеките соответствующую часть строки
Хотя я согласен с перспективой DBA не хранить несколько значений в одном поле, это выполнимо, как показано ниже, практично для логики приложения и некоторых проблем с производительностью.
Скажем, у вас 10000 групп пользователей, каждая из которых имеет в среднем 1000 членов. Вы можете иметь таблицу user_groups с такими столбцами, как groupID и membersID. Столбец membersID можно заполнить следующим образом: (', 10,2001,20003,333,4520,'), каждый из которых является идентификатором-членом, все разделяются запятой. Добавьте также запятую в начале и конце данных. Тогда ваш выбор будет использоваться как «%, someID,%».
Если вы не можете изменить свои данные ('01, 02,03 ') или аналогичные, скажем, вам нужны строки, содержащие 01, вы все равно можете использовать «select … LIKE '01,%' OR '%, 01' OR '% , 01,% '", который гарантирует, что он будет соответствовать, если в начале, в конце или внутри, избегая аналогичного числа (то есть: 101).
sql.fliplinux.com
MySQL Несколько соединений в одном запросе? Безопасный SQL
Вы можете просто добавить другое соединение следующим образом:
SELECT dashboard_data.headline, dashboard_data.message, dashboard_messages.image_id, images.filename FROM dashboard_data INNER JOIN dashboard_messages ON dashboard_message_id = dashboard_messages.id INNER JOIN images ON dashboard_messages.image_id = images.image_idОднако имейте в виду, что, поскольку это INNER JOIN , если у вас есть сообщение без изображения, вся строка будет пропущена. Если это возможно, вы можете сделать LEFT OUTER JOIN который вернет все ваши сообщения панели мониторинга и имя_файла только в том случае, если он существует (иначе вы получите нуль)
SELECT dashboard_data.headline, dashboard_data.message, dashboard_messages.image_id, images.filename FROM dashboard_data INNER JOIN dashboard_messages ON dashboard_message_id = dashboard_messages.id LEFT OUTER JOIN images ON dashboard_messages.image_id = images.image_idПросто добавьте еще одно соединение:
SELECT dashboard_data.headline, dashboard_data.message, dashboard_messages.image_id, images.filename FROM dashboard_data INNER JOIN dashboard_messages ON dashboard_message_id = dashboard_messages.id INNER JOIN images ON dashboard_messages.image_id = images.image_idЯ поделился своим опытом использования двух LEFT JOINS в одном SQL-запросе.
У меня 3 таблицы:
Таблица 1) Пациент состоит из столбцов PatientID, PatientName
Таблица 2) Назначение состоит из столбцов AppointmentID, AppointmentDateTime, PatientID, DoctorID
Таблица 3) Доктор состоит из столбцов DoctorID, DoctorName
Запрос:
SELECT Patient.patientname, AppointmentDateTime, Doctor.doctorname FROM Appointment LEFT JOIN Doctor ON Appointment.doctorid = Doctor.doctorId //have doctorId column common LEFT JOIN Patient ON Appointment.PatientId = Patient.PatientId //have patientid column common WHERE Doctor.Doctorname LIKE 'varun%' // setting doctor name by using LIKE AND Appointment.AppointmentDateTime BETWEEN '1/16/2001' AND '9/9/2014' //comparison b/w dates ORDER BY AppointmentDateTime ASC; // getting data as ascending orderЯ написал решение для получения формата даты, например «mm / dd / yy» (под моим именем «VARUN TEJ REDDY»)
sql.fliplinux.com
sql - Несколько запросов sql в одном результате
Я изо всех сил пытаюсь найти лучший способ написать этот запрос, чтобы использовать меньше запросов, если это возможно.. Мне интересно, может ли сводная таблица быть правильной?
Мои 3 отдельных запроса:
SELECT ISNULL(SUM(ps.UnitsSold), 0) AS UnitsSold, ISNULL(pg.[Description], 'Other') AS [Description] FROM dbo.ProductSales ps LEFT OUTER JOIN dbo.Product p ON ps.ProductID = p.ProductID LEFT OUTER JOIN dbo.ProductGroupings pg ON p.[Asin] = pg.[Asin] WHERE (ps.OrderDate BETWEEN GETDATE() - 10 AND GETDATE() - 3) AND ps.DistributionCentreID IN (3) GROUP BY pg.[Description], ps.DistributionCentreID SELECT ISNULL(SUM(ps.UnitsSold), 0) AS UnitsSold, ISNULL(pg.[Description], 'Other') AS [Description] FROM dbo.ProductSales ps LEFT OUTER JOIN dbo.Product p ON ps.ProductID = p.ProductID LEFT OUTER JOIN dbo.ProductGroupings pg ON p.[Asin] = pg.[Asin] WHERE (ps.OrderDate BETWEEN GETDATE() - 17 AND GETDATE() - 10) AND ps.DistributionCentreID IN (3) GROUP BY pg.[Description], ps.DistributionCentreID SELECT ISNULL(SUM(ps.UnitsSold), 0) AS UnitsSold, ISNULL(pg.[Description], 'Other') AS [Description] FROM dbo.ProductSales ps LEFT OUTER JOIN dbo.Product p ON ps.ProductID = p.ProductID LEFT OUTER JOIN dbo.ProductGroupings pg ON p.[Asin] = pg.[Asin] WHERE (ps.OrderDate BETWEEN GETDATE() - 374 AND GETDATE() - 367) AND ps.DistributionCentreID IN (3) GROUP BY pg.[Description], ps.DistributionCentreIDЭто приводит к таким же результатам (первый запрос):
UnitsSold Description 4154 desc1 764 desc2и т.д..
О чем подумать, описание (группа продуктов) может не существовать в одном из запросов, поэтому мне нужно это учитывать.
В идеале мне хотелось бы выглядеть примерно так:
Description UnitsSoldThisWeek UnitsSoldLastWeek UnitsSoldLastYear Desc1 54 45 37и т.д..
Любые вопросы, проблемы или сукинги из-за плохого запроса приемлемы, я рад улучшить свое понимание SQL.
Благодаря,
Майкл
источник поделитьсяqaru.site