CREATE TABLE PDIndicatorsHistory
(
RecId int PRIMARY KEY IDENTITY(1,1),
ItemId int,
ReportDate datetime,
PD int
);
INSERT INTO PDIndicatorsHistory (ItemId,ReportDate,PD) VALUES
(1, '2025-07-06', 2), (1, '2025-07-07', NULL), (1, '2025-07-08', NULL);
SELECT * FROM PDIndicatorsHistory;
CREATE FUNCTION dbo.GetPD
(
@prev_RecId INT, -- идентификатор предыдущей записи, её исходное состояние
@next_RecId int, -- идентификатор текущей записи, её исходное состояние
@prev_PD INT -- значения отдельных полей обновлённой предыдущей записи
)
RETURNS int
AS
BEGIN
-- требуемая сложная логика, опирающаяся на идентификаторы текущей и предыдущей записей
-- что позволяет получить значения полей записей ДО запуска SELECT или там UPDATE,
-- а также на значения полей модифицированного состояния предыдущей записи, переданных по отдельности
RETURN @prev_PD * 2;
END;
WITH
-- первый CTE, просто нумерует записи по возрастанию даты для каждого ItemId отдельно
cte1 AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY ItemId ORDER BY ReportDate ASC) rn
FROM PDIndicatorsHistory
),
-- рекурсивно обрабатываем записи в порядке возрастания номера
cte2 AS (
SELECT RecId, ItemId, ReportDate, PD, rn
FROM cte1
WHERE rn = 1 -- начинаем с первой
UNION ALL
SELECT cte1.RecId,
cte1.ItemId,
cte1.ReportDate,
dbo.GetPD(cte2.RecId, cte1.RecId, cte2.PD),
cte1.rn
FROM cte1
JOIN cte2 ON cte1.ItemId = cte2.ItemId
AND cte1.rn = cte2.rn + 1 -- а потом вторая, третья... пока не кончатся
)
-- посчитав значения, которые нужно использовать при обновлении, выполняем само обновление
UPDATE PDIndicatorsHistory
SET PD = cte2.PD
FROM cte2
WHERE PDIndicatorsHistory.RecID = cte2.RecId;
SELECT *
- только список конкретных полей. То же и в случае INSERT
- перечисляй все поля, в которые идёт вставка. Единственное место, где может быть звезда как список полей - это в COUNT(*)
.INSERT INTO new_table (column1, column2, ...)
SELECT column1, column2, ...
FROM old_table
WHERE ... ;
WITH cte AS (
SELECT id,
num,
LAG(num) OVER (ORDER BY id) lag_num
FROM test
)
SELECT id,
num,
CASE WHEN num <> 0
THEN SUM(CASE WHEN num <> 0 AND lag_num = 0 THEN 1 ELSE 0 END) OVER (ORDER BY id)
ELSE 0
END [group]
FROM cte
SELECT CASE WHEN [column] IS NULL
THEN 'sale'
WHEN CHARINDEX([column], '.') > 0
THEN LEFT([column], CHARINDEX([column], '.') - 1)
ELSE [column]
END AS [column]
FROM source_table;
как есть 2-я таблица с такимеже значениями только без .0 и без NULL . А мне в дальнейшем нужно сравнить эти 2 таблицы
SELECT *
FROM table1
JOIN table2 ON table1.[column] = CASE WHEN table2.[column] IS NULL
THEN 'sale'
WHEN CHARINDEX(table2.[column], '.') > 0
THEN LEFT(table2.[column], CHARINDEX(table2.[column], '.') - 1)
ELSE table2.[column]
END;
Select *
from Employees
where [Employee ID] != ALL ( SELECT 90 UNION SELECT NULL );
Но это такое убожество что я толком ничерта не понимаю
отличаются ли запросы sql MSSQL от Mysql
возможно ли сменить БД без нарушения функциональности софта.
WITH
cte1 AS ( SELECT id, col1 val FROM test UNION ALL
SELECT id, col2 FROM test UNION ALL
SELECT id, col3 FROM test ),
cte2 AS ( SELECT id, GROUP_CONCAT(val ORDER BY val) FIO
FROM cte1
GROUP BY id )
SELECT test.id, test.col1, test.col2, test.col3, GROUP_CONCAT(cte2_2.id) ids
FROM test
JOIN cte2 cte2_1 USING (id)
JOIN cte2 cte2_2 USING (FIO)
GROUP BY test.id, test.col1, test.col2, test.col3
id col1 col2 col3 ids
1 Иванов Иван Иванович 1,2
2 Иван Иванович Иванов 1,2
3 Петров Сергей Алексеевич 3,4,5
4 Петров Сергей Алексеевич 3,4,5
5 Сергей Алексеевич Петров 3,4,5
DEMOвыполняться будет на MS SQL Server, версию не могу сказать.
SELECT TOP 500 *
FROM [table]
WHERE NOT EXISTS ( SELECT NULL
FROM [Entities]
WHERE [column] = '2'
AND [table1].[Id] = [ClientTableId] )
CREATE TRIGGER tr
ON routes
AFTER INSERT
AS
UPDATE [user]
SET [update] = 1
FROM INSERTED
WHERE id = INSERTED.user_id;