Перекрестный запрос sql: Улучшение наглядности сводных данных с помощью перекрестного запроса
Содержание
запрос — Перекрестные SQL запросы
Имеется 3 запрос. Запрос 1 выводит 12 значений, запрос 2-11 и 3й -10. Как совместить их в 1 таблицу? Как я понял, необходимо использовать перекрёсные запросы, но не могу понять как это выполнить, помогите.
-------запрос1 select sp2.NAIM from sp2 inner join kdk1 on kdk1.kk02=sp2.kod_n where sp2.SPR='k02' group by sp2.naim -------запрос 2 select count(KDK1.n_kdk) from KDK1 inner join sp2 on sp2.KOD_N=kdk1.KK02 inner join KDK on kdk.N_KDK=KDK1.N_KDK where sp2.SPR='k02' and kdk.kpol=1 group by sp2.NAIM --------запрос 3 select count(KDK1.n_kdk) from KDK1 inner join sp2 on sp2.KOD_N=kdk1.KK02 inner join KDK on kdk.N_KDK=KDK1.N_KDK where sp2.SPR='k02' and kdk.kpol=2 group by sp2.NAIM
- запрос
- sql-server
- sql
1
Не вполне понятно, что вы понимаете под «совместить». Такой операции нет в SQL. 🙂
Лучше слов — показать желаемый результат.
Возможно так:
select sp2.NAIM ... UNION ALL select cast(count(KDK1.n_kdk) as varchar)... UNION ALL select cast(count(KDK1.n_kdk) as varchar)...
Тогда так, если не вникать:
select X.naim, y.cnt, z.cnt from ( select sp2.NAIM from sp2 inner join kdk1 on kdk1.kk02=sp2.kod_n where sp2.SPR='k02' group by sp2.naim ) X left join (select count(KDK1.n_kdk), sp2.NAIM from KDK1 inner join sp2 on sp2.KOD_N=kdk1.KK02 inner join KDK on kdk.N_KDK=KDK1.N_KDK where sp2.SPR='k02' and kdk.kpol=1 group by sp2.NAIM ) y on x.naim = y.naim left join (select count(KDK1.n_kdk), sp2.NAIM from KDK1 inner join sp2 on sp2.KOD_N=kdk1.KK02 inner join KDK on kdk.N_KDK=KDK1.N_KDK where sp2.SPR='k02' and kdk.kpol=2 group by sp2. NAIM ) z on x.naim = z.naim
4
Зарегистрируйтесь или войдите
Регистрация через Google
Регистрация через Facebook
Регистрация через почту
Отправить без регистрации
Почта
Необходима, но никому не показывается
Отправить без регистрации
Почта
Необходима, но никому не показывается
By clicking “Отправить ответ”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.
mysql — Перекрёстный запрос sql php
Вопрос задан
Изменён
3 года 1 месяц назад
Просмотрен
121 раз
Можете подсказать, пожалуйста, как мне вывести на странице в таблицу не id, которое в базе, а само значения, которое связано с другой таблицей.
К примеру, сейчас у меня вывод выглядит вот так:
№ Название датчика Значение Тип значения Дата 1 1 1 1 2020-05-01 12:00:05 3 1 5 2 2020-05-01 00:00:00 4 1 555 3 2020-05-21 00:00:00 8 1 2 1 2020-05-02 23:00:00 9 1 3 1 2020-05-05 00:04:00 10 1 6 1 2020-05-14 06:00:00
И запрос этот выглядит:
SELECT `id_data`, `data_id_model`, `data_value`, `data_id_type_value`, `data_date` FROM `data_indicators` WHERE data_id_station = '".$_GET['id']."'
Можете подсказать, как мне вывести правильно чтобы были данные, а не id?
База:
- php
- mysql
- sql
- phpmyadmin
- запрос
Необходимо связать таблицы data_indicators
, models
(модели датчиков), type_value
(имена парметров) по ключевым полям, они имеют пересечение в названии. В секцию FROM
добавляются имена таблиц, в WHERE
условия связи, после этого в SELECT
можно использовать столбцы из добавленых таблиц.
SELECT d.id_data, m.model_name, d.data_value, t.type_value_name, d.data_date FROM type_value t, models m, data_indicators d WHERE d.data_id_station = '".$_GET['id']"' AND m.id_model = d.data_id_model AND t.id_type_value = d.data_id_type_value
Добавил еще имя параметра, хорошо бы еще вывести единицу измерения type_value.type_value_unit
1
Зарегистрируйтесь или войдите
Регистрация через Google
Регистрация через Facebook
Регистрация через почту
Отправить без регистрации
Почта
Необходима, но никому не показывается
Отправить без регистрации
Почта
Необходима, но никому не показывается
By clicking “Отправить ответ”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.
Создание перекрестных запросов и сводных таблиц в SQL
В тех случаях, когда вам абсолютно необходимо выполнить перекрестный запрос в SQL, хранимая процедура Кейта Флетчера T-SQL позволит вам сделать это «на лету». Вы можете добавить его в свою базу данных и сразу начать кросс-таблицу, без каких-либо дополнительных настроек или изменений в вашем коде SQL. Проверьте это, а затем примите вызов кросс-таблицы. Если вы сможете составить перекрестный отчет, отображающий стоимость заказа по клиентам, по кварталам, используя хранимую процедуру, вы можете выиграть столь желанный приз!
Иногда вам просто необходимо сгенерировать перекрестную таблицу в SQL. Система отчетности не годится для этого, и невозможно встроить эту функциональность в приложение. Например:
- Возможно, вы используете решение для создания отчетов, которое не поддерживает эту функцию.
- Вы используете устаревшее приложение, с которым лучше не возиться.
- Вы хотите экспортировать некоторые данные, уже представленные в требуемом формате, в текстовый файл.
Именно для этих исключительных случаев я решил написать динамическую хранимую процедуру перекрестной таблицы.
Скорее исключение, чем правило
Существует общее правило, согласно которому манипулирование данными такого рода лучше оставить на уровне приложений или отчетов системы, и на то есть веские причины. Основная роль ядра базы данных SQL заключается в хранении и поиске информации, а не в ее сложной обработке. Любой, кто пытался превратить данные в SQL в осмысленный набор информации, используя сложный набор бизнес-правил, вероятно, согласится с тем, что SQL имеет тенденцию отговаривать вас от этого, и чем более причудливым и творческим вы пытаетесь сделать свое решение, тем сильнее становится это уныние.
Говорят, что если вы можете что-то сделать, это не значит, что вы должны это делать. Верно, но я, например, думаю, что применимо и обратное. Если вам кажется, что вы чего-то не можете, это не значит, что вы не должны этого делать. Это уравновешивание, которое требует тщательного рассмотрения. Я нашел несколько приложений, для которых эта хранимая процедура была идеальным решением — я намекнул на них в первом абзаце. Однако есть столько же, если не больше, где его не следует использовать. Хранимая процедура может отрицательно сказаться на производительности, если она используется неправильно или используется в дорогом или большом источнике данных. Я оставляю вас с советом, что описанный здесь сценарий следует использовать осторожно и экономно, а не распылять волей-неволей на ваши базы данных.
Требования
Весь мой демонстрационный код будет использовать надежную базу данных Northwind . По умолчанию он поставляется с SQL Server 2000, но если вы избавились от него или используете Server 2005, вы можете загрузить его с веб-сайта Microsoft.
После загрузки и подключения Northwind создайте хранимую процедуру sys_CrossTab в базе данных, и все готово.
Простой перекрестный запрос
В базе данных Northwind есть таблица под названием Categories , которая используется для разделения всего набора продуктов на восемь отдельных групп, а именно: напитки, приправы, кондитерские изделия, молочные продукты, зерновые/хлопья, мясо/птица, продукты и морепродукты. . Если бы торговая компания «Северный ветер» была реальным юридическим лицом, было бы немыслимо, чтобы один из счетчиков фасоли запросил отчет с указанием общей стоимости заказов, размещенных по годам и категориям. Это была бы прекрасная возможность попробовать кросс-таб-запрос. Самый простой способ сделать это — использовать CASE функция.
1 2 3 4 5 6 7 8 9 9 0003 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 9 0003 26 27 28 29 | SELECT YEAR(ord. OrderDate) YEAR, SUM(CASE prod.CategoryID WHEN 1 THEN det.UnitPrice * det.Quant ity ELSE 0 END) Напитки, SUM(CASE prod.CategoryID WHEN 2 THEN det.UnitPrice * det.Quantity ELSE 0 END) Приправы, SUM(CASE prod.CategoryID WHEN 3 THEN det.UnitPrice * det.Quantity ELSE 0 КОНЕЦ) Кондитерская, SUM(CASE prod.CategoryID WHEN 4 THEN det.UnitPrice * det.Quantity ELSE 0 END) [Молочные продукты], SUM(CASE prod.CategoryID WHEN 5 THEN det.UnitPrice * det.Quantity ELSE 0 КОНЕЦ) [Зерна/Злаки], СУММА(CASE prod.CategoryID WHEN 6 THEN det.UnitPrice * det.Quantity ELSE 0 END) [Meat/Poult ry], SUM(CASE prod.CategoryID WHEN 7 THEN det.UnitPrice * det.Quantity ELSE 0 END) Produce, SUM(CASE prod. CategoryID WHEN 8 THEN det.UnitPrice * det.Quantity ELSE 0 END) Морепродукты
ОТ Заказы ord
INNER JOIN [Сведения о заказе] det ON det.OrderID = ord.OrderID
INNER JOIN Products prod ON prod.ProductID = det. ID продукта
СГРУППИРОВАТЬ ПО ГОДУ(Order.OrderDate)
ORDER BY YEAR(order.OrderDate) |
Это вернет
Итак, вы быстро набираете запрос, показываете бухгалтеру, как импортировать данные в электронную таблицу Excel, и идете за пинтой, чтобы отпраздновать свою изобретательность.
Вскоре после этого парень решает, что отчет с данными недостаточно детализирован, и хотел бы, чтобы аналогичный отчет был разделен по названиям продуктов, а не по категориям. Товаров 77, поэтому в нем задействовано еще несколько CASE операторов. Вы тихонько ворчите себе под нос, демонстрируя свое мастерство вырезания и вставки, и создаете новый отчет, показывающий разбивку по продуктам.
Благодаря вашему отчету компания решает, что несколько линеек продуктов не приносят должного дохода, поэтому они отказываются от этих продуктов и добавляют несколько новых. Бухгалтер встревожен, обнаружив, что отчет, который вы написали для него, по-прежнему показывает старые продукты и не включает в отчет новые продукты. Здесь ваше быстрое решение начинает идти на юг.
Введите динамическую кросс-таблицу
Наступает момент, когда поддержание всех этих «жестко закодированных» кросс-таблиц требует больше усилий, чем тратить некоторое время на разработку более универсального, постоянного решения. Решение, к которому я пришел, все еще по существу использует функцию CASE для перекрестной таблицы данных. Единственное реальное отличие состоит в том, что список операторов CASE создается динамически на основе данных, которые вы хотите использовать для описания столбцов.
Созданная мной хранимая процедура запустилась как простая динамическая Построитель инструкций CASE с использованием sp_executesql . Это сразу же стало полезным, и вскоре люди задавали вопросы: « Как мне заставить его делать …». Постепенно он превратился в монстра, которым он является сегодня. Намерение всегда состояло в том, чтобы иметь процедуру, которая была бы настолько универсальной и переносимой, чтобы ее можно было добавить в любую базу данных, а кросс-таблицы можно было бы создавать немедленно без какой-либо дополнительной настройки или изменения в коде SQL. Хотя простота использования, возможно, немного пострадала, я чувствую, что основная цель была достигнута.
Используя хранимую процедуру
Для начала давайте создадим набор результатов кросс-таблицы со списком компаний в первом столбце, именем контакта в компании во втором столбце и списком товаров на складе из третьего столбца. вперед. Внутри сетки мы укажем общую стоимость заказов, размещенных этой компанией для этого продукта. Он должен быть отсортирован по названию компании.
SQL-запрос, который возвращает исходные данные, которые нам нужны:
1 2 3 4 5 6 7 8 9 9 0003 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 9 0003 26 27 28 29 30 31 32 33 34 | SELECT cus. CompanyName, cus.ContactName, prod.ProductID, prod.ProductName, det.UnitPrice, det.Quantity
ОТ Заказы ord
INNER JOIN [Сведения о заказе] det ON det .OrderID = ord.OrderID
INNER JOIN Products prod ON prod.ProductID = det.ProductID
INNER JOIN Customers cus ON cus.CustomerID = ord.CustomerID И вот как мы это сделаем: EXEC sys_CrossTab 9000 2 ‘Order ord внутреннее соединение [Сведения о заказе] det on det.OrderID = ord.OrderID внутреннее соединение Товары prod on prod.ProductID prod.ProductID = det.ProductID внутреннее соединение on cus.CustomerID = ord.CustomerID’, — @SQLSource ‘prod.ProductID’, — @ColFieldID
‘prod. ProductName’, — @ColFieldName ‘prod.ProductName’, — @ColFieldOrder ‘det.UnitPrice * det.Quantity’, — @CalcFieldName ‘cus.CompanyName, cus.ContactName’, — @RowFieldNames NULL, — @TempTableName ‘сумма’, — @CalcOperation 0, — @Debug NULL, — @SourceFilter 9000 3 0, — @NumColOrdering ‘Всего’, — @RowTotals NULL, — @ColTotals ‘CompanyName’, — @CalcFieldType |
Первые несколько возвращенных строк и столбцов будут
Структура хранимой процедуры
Если вы хотите отрегулировать процедуру, сделать ее более эффективной, возможно, адаптировать ее к вашим индивидуальным потребностям и вырезать некоторые функциональность, которую вы никогда не будете использовать, вам может быть интересно, как она была собрана. Если у вас есть идеи, как сделать что-то лучше, пожалуйста, поделитесь ими со всеми нами. Хранимая процедура достаточно хорошо задокументирована, и вы сможете разобраться в коде.
Вы заметите, что сразу несколько varchar(8000) объявлений переменных. В самом начале проекта я обнаружил, что varchar(8000) недостаточно для чего-либо, кроме самого тривиального запроса. Единственный способ обойти эту проблему хранения — создать диапазон этих переменных, и по мере заполнения первого я начинал добавлять информацию в следующий. Для каждой части окончательного запроса, который мы строим, был объявлен ряд переменных, а именно CASE операторов, список полей выбора, итоги и так далее.
Первым делом необходимо определить имена столбцов кросс-таблицы. Это будет первый из двух запросов к вашим исходным данным. Мы вставляем все отдельные имена столбцов в таблицу памяти (#Columns ) в том порядке, в котором они должны появляться в кросс-таблице. Если вы выбрали отображение итогов по столбцам, они будут рассчитаны и сохранены на этом этапе.
Затем удаляются все префиксы из полей строк. Это важно, так как мы будем группировать по этим полям, а псевдонимы или ссылки на таблицы могут усложнить сгенерированный запрос.
Затем я определяю курсор, который перемещается по элементам, которые были вставлены в таблицу памяти #Columns . При этом создаются операторы CASE , которые используются для выполнения агрегатных функций над исходными данными. Некоторая работа также выполняется над созданием частей оператора SQL для сумм строк и столбцов, а также оператора вставки в целевую временную таблицу, если эти параметры были выбраны.
После того, как мы собрали фрагменты, мы связываем их вместе и запускаем запрос. Если вы посмотрите на код хранимой процедуры, то увидите, что я определил восемь различных сценариев в зависимости от того, решили ли мы сохранять данные во временную таблицу или использовать итоговые данные по строкам и столбцам. Определяется применимый сценарий, после чего окончательный оператор SQL соответствующим образом объединяется вместе с отладочной версией, если отладка была включена. Это будет второй запрос к вашему источнику данных.
Было бы трудно описать хранимую процедуру более подробно, если не вдаваться в подробности. Тем не менее, я чувствую, что код адекватно прокомментирован, и у вас не должно возникнуть особых проблем с внесением изменений, если вы решите это сделать. Лучший совет, который я могу предложить, — использовать средства отладки, так как вы сразу же увидите эффект ваших изменений на сгенерированном коде SQL.
Параметры хранимой процедуры, объяснение
Прототип хранимой процедуры выглядит следующим образом:
1 2 3 4 5 6 7 8 9 9 0003 10 11 12 13 14 15 16 | CREATE PROC [dbo].[sys_CrossTab] @SQLSource varchar(8000), @ColFieldID varchar(8000), @ColFieldName varchar(8000), @ColFieldOrder varchar(8000), @CalcFieldName varchar(8000), @ RowFieldNames varchar(8000), @TempTableName varchar(200) = null, @ CalcOperation varchar(50) = ‘sum’, @Debug bit = 0, @SourceFilter varchar(8000) = null, @NumColOrder ing бит = 0, @RowTotals varchar(100) = null, @ColTotals varchar(100) = null, @OrderBy varchar(8000) = null, @CalcFieldType varchar(100) = ‘int’ 90 003 |
Моему исходному приложению не нужны были nvarchar s, а мне действительно нужно было дополнительное место для хранения, поэтому я решил использовать тип данных varchar . Я бы порекомендовал вам изменить их на nvarchar s, если вы хотите, чтобы код был культурно-безопасным.
Приведены некоторые подробности назначения и использования каждого параметра. Если мое описание кажется вам слишком расплывчатым, взгляните на приведенный выше пример скрипта и результат, который он сгенерировал, или, что еще лучше, запустите скрипт сами и поэкспериментируйте с ним.
@SQLSource
Первый параметр, @SQLSource , именно таков; источник данных, из которого вы хотите создать кросс-таблицу. Это может быть имя таблицы, имя представления, имя функции или даже предложение FROM оператора SELECT , как мы использовали в примере. Еще раз взгляните на представленную мной инструкцию SQL и сравните ее с текстом, используемым для параметра @SQLSource . По сути, это часть оператора SQL после Ключевое слово FROM , вплоть до предложения WHERE , если оно существует, но не включая его. Если вы хотите использовать таблицу, представление или функцию, используйте только имя и, возможно, псевдоним — не используйте ключевое слово SELECT .
@ColFieldID
Нам нужно решить для каждой строки исходных данных, какому столбцу присвоить значения. Параметр @ColFieldID используется для выбора столбца, который будет использоваться для этой функции. В нашем примере используется поле ProductID . Количество различных значений, которые этот столбец имеет в исходных данных, скажет вам, сколько столбцов будет использоваться в кросс-таблице. Это важное соображение, особенно если вы хотите использовать результаты перекрестной таблицы в электронной таблице Excel, так как Excel накладывает верхний предел на количество столбцов, которые он может обрабатывать.
@ColFieldName
Используйте @ColFieldName, чтобы указать имя поля, которое будет содержать заголовки для каждого столбца кросс-таблицы. Это может быть то же поле, которое используется для @ColFieldID .
@ColFieldOrder
Если вам требуется сортировка столбцов, вы можете указать поле, по которому должно происходить упорядочение. Параметр @ColFieldOrder должен содержать имя этого поля заказа. Это тоже может быть то же поле, что и @ColFieldID 9.0026 . Вы также можете установить параметр @NumColOrdering , если порядок важен. По умолчанию столбцы будут отсортированы в алфавитно-цифровом порядке. Если вам требуется численная сортировка, установите для @NumColOrdering значение 1. Описание этого параметра даст немного больше деталей.
@CalcFieldName
@CalcFieldName должно содержать имя поля, которое будет использоваться для создания данных в сетке кросс-таблицы. Это будут базовые данные подсчета, суммы, среднего значения или любой другой агрегатной функции, которую вы выберете. Естественно, вы должны убедиться, что тип данных этого поля соответствует операции, которую вы хотите выполнить. Вы не можете выполнить SUM операция в поле varchar , хотя операция COUNT вполне приемлема.
@RowFieldNames
Здесь вы предоставите разделенный запятыми список, состоящий из одного или нескольких имен полей, которые будут использоваться в качестве первых нескольких столбцов сетки. Агрегатная функция, которую вы собираетесь выполнять, будет выполняться как функция группировки полей, которые вы укажете здесь, поэтому выбирайте их с умом.
@TempTableName
Иногда перекрестная таблица является не окончательным результатом, а средством достижения цели. Возможно, вы захотите выполнить дополнительные запросы к сгенерированным данным перекрестной таблицы или соединить их с другими таблицами. По этой причине был добавлен параметр @TempTableName . Он позволяет вставлять данные перекрестной таблицы во временную таблицу, которую затем можно использовать для дальнейшей обработки.
Здесь есть ряд предостережений. Во-первых, вам нужно создать временную таблицу, прежде чем вызывать хранимую процедуру перекрестной таблицы (из-за правил области видимости SQL). Однако при создании таблицы вам необходимо указать хотя бы один столбец. Проще всего сделать что-то вроде
CREATE TABLE #CrossTab (фиктивный TINYINT NULL) |
Затем вы передадите имя временной таблицы (в данном случае #CrossTab ) хранимой процедуре. После завершения создания кросс-таблицы ваша временная таблица будет содержать информацию кросс-таблицы в дополнение к вашему фиктивному полю. Если, как и я, вы считаете, что фиктивное поле «тратится впустую», вы можете объявить его как поле идентификации, тем самым добавив порядковый номер в свою таблицу.
CREATE TABLE #CrossTab (последовательность INT IDENTITY(1,1)) |
Пользователей вашего запроса гораздо меньше беспокоит порядковый номер, чем пустой, бесполезный столбец в начале набора результатов.
@CalcOperation
Здесь мы сообщаем хранимой процедуре, что делать с исходными данными, которые мы предоставляем. Приемлемыми значениями этого параметра являются любые агрегатные функции SQL, а именно AVG , SUM , COUNT , MIN , MAX и им подобные. Убедитесь, что вы сопоставляете операцию с типом данных, то есть не SUM ming данных varchar.
@Debug
Параметр @Debug , отключенный по умолчанию, может оказаться очень удобным. Когда включено (установлено на 1), он распечатает код SQL, используемый для создания кросс-таблицы. Если вы не ожидаете, что столбцы вашей кросс-таблицы изменятся, вы можете запустить SQL, распечатанный кодом отладки, вместо использования хранимой процедуры, что будет значительно эффективнее. Таким образом, вы можете использовать хранимую процедуру в качестве инструмента генерации SQL.
Обратите внимание, что итоги строк не будут вычисляться отладочным SQL. Хранимая процедура «жестко закодирует» итоги, рассчитанные ею во время запуска.
@SourceFilter
@SourceFilter позволяет ввести некоторый код SQL для фильтрации исходных данных до того, как они будут объединены в перекрестные таблицы. Это будет код предложения WHERE , соответствующий коду предложения SELECT , указанному в параметре @SQLSource . Нет причин, по которым вы не можете включить WHERE как часть данных, передаваемых @SQLSource , хотя мне проще и удобнее указывать его отдельно.
@NumColOrdering
Если вы хотите, чтобы ваши столбцы были расположены в определенном порядке, вы укажете имя поля, чтобы упорядочить их по параметру @ColFieldOrder , и вы будете использовать поле @NumColOrdering чтобы указать, как будет происходить заказ. При значении 0 (по умолчанию) данные будут отсортированы в алфавитно-цифровом порядке, а при значении 1 — в числовом.
Если вы не уверены в разнице между ними, рассмотрите следующий список: 2, 1, 10, 11, 20, 100. При численной сортировке это будет 1, 2, 10, 11, 20. , 100. Однако сортировка по алфавиту даст 1, 10, 100, 11, 2, 20. Естественно, сортировка по буквам и цифрам также будет обрабатывать A, B и C, тогда как сортировка по числам вызовет ошибку несоответствия типов.
@RowTotals
Если для этого параметра задано значение, отличное от NULL, в качестве последнего столбца результирующего набора будет добавлен дополнительный столбец (имя столбца является приведенным здесь значением) и будет содержать сумму перекрестных значений. значения табуляции для каждой строки.
@ColTotals
Если установлено значение, отличное от NULL, в качестве последней строки результирующего набора будет добавлена дополнительная строка, которая будет содержать сумму значений перекрестной таблицы для каждого столбца. Однако есть ряд вещей, на которые следует обратить внимание. Во-первых, вам нужно будет передать имена полей, уже заключенные в кавычки, в параметр. Например, если вы хотите, чтобы строка была помечена как Total, вам нужно установить @ColTotals на «Total». Во-вторых, вам нужно будет указать столько значений, сколько полей, которые вы указали в Параметр @RowFieldNames . В нашем примере мы использовали два поля, поэтому нам нужно указать два значения для @ColTotals . Наконец, эта общая строка может не обязательно отображаться в нижней части набора результатов, в зависимости от того, указали ли вы значение параметра @OrderBy . Итоги добавляются 90 193 до 90 194 к сортируемой кросс-таблице.
Если вы включили опцию отладочной печати, предоставленный вам код SQL также не будет динамически вычислять итоги по столбцам. Итоги будут определены во время первоначального выполнения хранимой процедуры, и эти фиксированные значения затем присоединятся к остальной части результирующего набора.
@OrderBy
Параметр @OrderBy позволяет указать условие ORDER BY . Если используется, это должно быть одно или несколько полей, используемых в параметре @RowFieldnames . Если вы используете @ColTotals , имейте в виду, что строка итогов столбца будет считаться частью данных кросс-таблицы и будет упорядочена вместе с другими строками.
@CalcFieldType
Тип данных вычисляемых полей в сетке кросс-таблицы можно указать с помощью Параметр @CalcFieldType . По умолчанию это будет типов INT . Установите тип, соответствующий типу выполняемой операции и типу данных, которые вы ожидаете увидеть в кросс-таблице.
Вызов!
Если вы собираетесь опробовать хранимую процедуру, вы также можете получить кое-что за свои усилия. Редактор Simple-Talk Тони Дэвис любезно предложил спонсировать приз за первые три правильных ответа на вызов. Он также основан на базе данных Northwind, и вам нужно будет сделать следующее:
Скомпилируйте отчет в виде кросс-таблицы, отображающий стоимость заказа по клиентам за квартал. Вы также должны сгруппировать клиентов по стране, в которой они находятся. Отсортируйте список по стране, а затем по названию компании. Отображать итоги как по строке, так и по столбцу, чтобы они отображались справа и внизу отчета соответственно. Я включил снимок экрана, чтобы вы могли видеть, как должен выглядеть отчет.
Опубликуйте исходный код своего решения в комментариях к этой статье (или отправьте его Тони по адресу [email protected]).
В заключение
Вы обнаружите, что как только вы сделали одну кросс-таблицу, вы почти сделали их все. Наибольшая трудность заключается в том, чтобы действительно решить, что вы хотите отобразить, а затем собрать исходные данные для хранимой процедуры. Фактическое создание кросс-таблицы — это просто вопрос сопоставления имен полей с входными параметрами.
Я надеюсь, что вы найдете эту хранимую процедуру столь же полезной, как и я — это один из самых ценных предметов в моем наборе инструментов. Если вы обнаружите для него какое-то новое применение или новую идею о том, как его немного улучшить, поделитесь им с нами. Мне, например, было бы интересно услышать об этом.
sql — для построения перекрестного запроса с подробностями
спросил
Изменено
1 год, 3 месяца назад
Просмотрено
206 раз
Мне нужно построить перекрестный запрос в ms access, но вместо сводной информации мне нужно показать детали.
У меня есть таблица вида:
Дата Teamname Teammemebername
Кросс-таблица должна содержать:
- Дата в качестве заголовка строки
- Название команды в качестве заголовка столбца
- И имена членов команды в сводном разделе
Как это сделать?
ID ScheduleDate TeamCode TeamMemberCode 5585 04.03.2022 NT СЗ 5586 04.03.2022 УГРЛ РН 5587 04.03.2022 УШРТ КН 5588 04.03.2022 УШРТ КИ 5589 04.03.2022 УШРТ РФ 5590 11.03.2022 НТ МФ 5591 11.03.2022 USHRL QD 5592 11.03.2022 УШРТ СЗ 5593 11.03.2022 УШРТ КН 5594 11.03.2022 УШРТ КИ
- sql
- ms-access
- crosstab
- ms-access-2016
Неверный первый ответ:
TRANSFORM First(tblTeamdata.Teammemebername) AS FirstMembername
ВЫБЕРИТЕ таблицу tblTeamdata.DAT
ИЗ tblTeamdata
СГРУППИРОВАТЬ ПО tblTeamdata.DAT
PIVOT tblTeamdata.Teamname;
Поскольку каждая ячейка кросс-таблицы может иметь несколько MemberCodes, вам придется использовать функцию для возврата списка этих имен. Функция должна иметь дату и код команды в качестве параметров.
Имена функций (дата как вариант, команда как вариант) Dim res$, sql$ Dim rs As DAO.Recordset Если IsNull(дата) или IsNull(команда) Тогда имена = ноль Еще sql = "ВЫБЕРИТЕ * ИЗ Teamdata" sql = sql & " Где ScheduleDate = #" & dat & "#" sql = sql & " AND TeamCode=""" & team & """" sql = sql & " Заказ по TeamMemberCode;" Установить rs = CurrentDb.OpenRecordset (sql) Делать до rs.EOF Если res <> "" Тогда res = res & "," res = res & rs!TeamMemberCode rs.MoveNext Петля rs.Закрыть имена = разрешение Конец, если Конечная функция
ПРЕОБРАЗОВАНИЕ имен ([ScheduleDate], [Teamcode]) КАК Результат
ВЫБЕРИТЕ TeamData.ScheduleDate
ОТ TeamData
СГРУППИРОВАТЬ ПО TeamData.ScheduleDate
PIVOT TeamData.TeamCode;
Результатом запроса с вышеуказанным набором данных будет:
ScheduleDate NT USHRL USHRT
04.