Ответы пользователя по тегу SQL
  • Выбрать первую и последнюю запись группы?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    Не работал с PostgreSQL, но чисто на знании MS SQL могу предложить такой вариант
    SELECT ticket_number, some_id 
    FROM (
    SELECT ticket_number, some_id,
     rank() OVER (PARTITION BY ticket_number ORDER BY some_id DESC) RnkDESK,
     rank() OVER (PARTITION BY ticket_number ORDER BY some_id ASC) RnkASC
    FROM table ) x
    WHERE X.RnkDESK = 1 OR X.RnkASC = 1
    Ответ написан
    1 комментарий
  • Почему mssql выдает ошибку?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    DELETE e
    FROM #employees e
    INNER JOIN (
    	SELECT id
    		,RANK() OVER (PARTITION BY pass_num ORDER BY ID) RNK
    	FROM #employees
    	) X ON X.id = e.id
    WHERE x.RNK > 1
    Ответ написан
    Комментировать
  • Как оптимизировать MSSql запрос?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    Буду честен. Ваш запрос не то что понять, его прочитать сложно.

    1. Поделите запрос на части и используйте времянки.
    2. Необязательно помещать каждый JOIN в подзапрос. Сделайте вида:
    SELECT  
    FROM TABLE
    inner join  TABLE2 ON ...
    inner join  TABLE3 ON ...

    3. Зачем писать условие в конце, когда можно сделать это прямо в JOUN-е
    SELECT *  FROM
     [OTD_db].[dbo].[DocumentsA] As [CurStatID]  
     INNER JOIN [OTD_db].[dbo].[Status] AS [Vv1] ON [Vv1].[StatusID] = [CurStatID].[CurrentStatusID] and [Vv1].[Name] Like 'Шаблон'

    4. Если данных в таблице будет много и запрос будет работать долго, то после указания таблицы или ее псевдонима допишите WITH (NOLOCK). Это снимет блокировку с таблицы на время работы запроса.
    5. Старайтесь не использовать вложенные запросы. типа where ПОЛЕ in (select from TABLE). Это сильно утяжеляет запрос.
    Ответ написан
  • Как реализовать блокировки в базе данных MSSQL?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    Может многие меня не поддержат. Но у меня стояла задача разблокировать редактирование, при этом оставив просмотр для остальных. Оставлять одну только проверку версии казалось мало, а реализовывать через транзацию побоялся: неизвестно как будет себя вести изоляция, если ею раньше не пользовался.
    Реализация была через три дополнительных поля и пару процедур. Три на самом деле избыточно. Хватило бы и два. В общем этакий велосипед.
    Поля в заголовке:
    • Идентификатор пользователя UserEditGUID uniqueidentifier
    • Дата когда пользователь начал редактировать BeginEdit datetime
    • Не особо нужное поле isEdit bit


    И собственно процедура блокировки:
    ALTER PROCEDURE [dbo].[LockUnLockOrder]
    	@HeadGUID uniqueidentifier, @UserGUID  uniqueidentifier, @Lock bit
    	
    AS
    BEGIN
    	-- SET NOCOUNT ON added to prevent extra result sets from
    	-- interfering with SELECT statements.
    	SET NOCOUNT ON;
    	
    	if @HeadGUID is null or @UserGUID is null or @Lock is null 
    	begin
    	raiserror('Процедура LockUnLockOrder: Неинициализированный параметр',16,1)
    	return -1
    	end
    if V_ORDER.dbo.CheckEditStatus(@HeadGUID,@UserGUID) = 1
    begin
    	if 	@Lock = 1			
    	UPDATE [V_ORDER].[dbo].[OrderHeader]
    	SET isEdit = 1
    		,BeginEdit = getdate()
    		,UserEdit = @UserGUID
    	WHERE GUID = @HeadGUID
    	else 
    	if 	@Lock = 0			
    	UPDATE [V_ORDER].[dbo].[OrderHeader]
    	SET isEdit = 0
    		,BeginEdit = null
    		,UserEdit = null 
    	WHERE GUID = @HeadGUID
    	return 1
    end
    else raiserror('Невозможно изменить статус заказа',16,1)
    end


    И функция проверки возможности редактирования. Если пользователь открыл час назад, и не закрыл, то разрешение на редактирование выдается.
    -- =============================================
    -- Author:		k1lex
    -- Create date: 20160818
    -- Description:	функция возвращает разрешение редактирования заказа. 1 - можно редактировать. 0 - нельзя
    -- =============================================
    ALTER FUNCTION [dbo].[CheckEditStatus]
    (
    	-- Add the parameters for the function here
    	@HeadGUID uniqueidentifier, @UserGUID  uniqueidentifier
    )
    RETURNS bit
    AS
    BEGIN
    DECLARE @bit BIT
    
    IF (
    		SELECT COUNT(*)
    		FROM [V_ORDER].[dbo].[OrderHeader] O WITH (NOLOCK)
    		WHERE O.GUID = @HeadGUID
    			AND (ISNULL(O.IsReadOnly, 0) = 1 OR (O.userEdit != @UserGUID AND O.IsEdit = 1 AND DATEDIFF(HOUR, BeginEdit, GETDATE()) < 1)	
    			and [Status]=1
    			)
    		) = 0
    	SET @bit = 1
    ELSE
    	SET @bit = 0
    
    RETURN @bit
    END


    И поддержу Петр , что нужна проверка даты последнего изменения. На тот случай, если кто-то откроет, и вспомнит через три часа что открыл и отредактирует уже отредактированное.
    Ответ написан
    1 комментарий
  • Как сделать в MSSQL поиск дубликатов в одной из колонок, при условии совпадения по другой колонке и отсутствия дубликатов в третьей?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    select 
    t1.id ,  t1.project_id ,  t1.sum_1 ,  t1.sum_2
    from table t1
    inner join 
    ( select project_id , COUNT(sum_1) ac CT from  table group by project_id ) t2 ON t1.project_id=t2.project_id  and t2.CT>1
    inner join 
    ( select project_id , COUNT(sum_2) ac CT from  table group by project_id ) t3 ON t1.project_id=t3.project_id  and t3.CT=1
    Ответ написан
    Комментировать
  • WHERE в SELECT SQL?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    SELECT [Поле группировки], sum(что сложить) FROM `table`  
     WHERE <условие>
     group by [Поле группировки]


    или

    SELECT [Поле группировки], sum(что сложить) FROM `table`  
     group by [Поле группировки]
    having [условие]


    Запросы работают примерно одинаково. Только в первом мы сначала накладываем условие на таблицу, а потом группируем. А во втором сначала получаем данные и накладываем условие.
    Ответ написан
    Комментировать
  • Как остановить count (sql запрос) после того как найдет 1 запись?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    А зачем вам выбирать количество если вы и так выбираете только 1 ???
    Выбирайте 1 ID , а дальше уже по ситуации.
    Ответ написан
  • Как выбрать из БД участки, у которых увеличилась площадь?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    IF OBJECT_ID('tempdb..#testtable') IS NOT NULL	DROP TABLE #testtable
    
    create table #testtable (number nvarchar(255), spac money, dateR date)
    insert into #testtable
    (number, spac, dateR)
    values
    (1,10,'20140505'),
    (1,11,'20141212'),
    (2,50,'20160505'),
    (2,40,'20160508')
    
    IF OBJECT_ID('tempdb..#testtableRNK') IS NOT NULL	DROP TABLE #testtableRNK
    
    select * ,
    rank() over (partition by Number order by dateR desc) as RNK
    into #testtableRNK
    from #testtable
    
    select * from #testtableRNK  r1
    inner join #testtableRNK  r2 ON r1.number= r2.number and r2.RNK=(r1.RNK+1)  and r1.RNK=1 and r2.spac< r1.spac
    Ответ написан
    Комментировать
  • SQL запрос, найти разницу в 2 столбцах?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    SELECT id2
    FROM table t1
    left join table t2 ON t1.id2=t2.id1
    where t2.id1 is null

    А вообще сохраните картинку себе на память
    2ee4f7db62d3481e9df4698c2af7a97d.jpg
    Ответ написан
    Комментировать
  • В чем разница между LINQ to SQL и Entity Framework и когда, что лучше использовать?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    Когда-то потратил очень много времени на поиск того что же лучше и чем они вообще отличаются.
    Поищите в интернете, там всё по полочкам разложено.
    Но если коротко: Используйте Entity Framework. LINQ to SQL уже давно устарел и проект фактически закрыт. EF же развивается, хоть и с черепашей скоростью
    Ответ написан
    Комментировать
  • Поочередно подставить значения в SQL запрос?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    Сформируйте временную таблицу где будут два поля: 1е - первое значение type, 2e - второе значение.
    Допустим это будет таблица tmp_type с полями type1 и type2
    Затем пишем такой запрос:
    SELECT  tmp_type.type1,tmp_type.type2,sum(money) FROM `accounts` 
    inner join tmp_type ON tmp_type.type1 =accounts.type or tmp_type.type2 =accounts.type
    group by tmp_type.type1,tmp_type.type2
    WHERE date >= (CURDATE()-1) AND date < CURDATE()
    Ответ написан
    Комментировать
  • Как сделать группировку по двум полям и из них выбрать максимальную группу?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    Можно используя RANK.
    SELECT 
    id_new,
    id_user
    FROM (
    SELECT 
         id_new,
        id_user, 
       RANK() OVER (PARTITION BY id_user ORDER by id_new DESK ) AS RNK
    FROM tbl_bookmarks
    GROUP BY id_user,id_new 
    ) X WHERE RNK=1

    А вообще самый правильный вариант еще проще. Вы же делаете группировку. Что мешает сделать так:
    SELECT MAX(id_new),id_user
    FROM tbl_bookmarks
    GROUP BY id_user
    Ответ написан
  • Как убрать повторы из выдачи?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    Добавляете в основной запрос
    RANK() over(partition by table2.id order by table1.id)  as RNK

    а потом из выдачи выбираете только те, у которых RNK=1
    select * from 
    (
    SELECT *,  RANK() over(partition by table2.id order by table1.id)  as RNK
     FROM `table1` INNER JOIN `table2` WHERE `table1`.`date`=CURDATE()
    ) X  where X.rnk=1
    Ответ написан
  • Какой индекс выбрать ASC или DESC?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    Я не очень пойму чего вы ходите добиться.
    ASC и DESC всего лишь направления для сортировки.

    SELECT TOP 50 * FROM table ORDER BY id DESC - даст вам 50 последних записей
    SELECT TOP 50 * FROM table ORDER BY id ASC - даст вам 50 первых записей.

    Поясните, может это я еще дзен не постиг?
    Ответ написан
    1 комментарий
  • MS Acccess, SQL не могу изменить тип данных, детали в описании?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    По моему проще создать дополнительное поле типа числовое или денежное. Перенести данные из старого поля с конвертацией. Старое поле удалить, новое переименовать в старое.
    Если не знаете как написать запрос:
    UPDATE таблица
    SET <Новое поле> = CAST(<старое поле> as <тип данных>
    Ответ написан
  • Почему не работает следующий Prepared запрос?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    Вы пытаетесь в качестве параметра передать таблицу. По моей практике это не очень возможно.
    Я в таком случае в транзации формирую времянку на сервере, передаю ее в нее таблицу и дальше делаю требуемые операции.
    Но сейчас смотря на ваш код я не очень понимаю зачем передавать таблицу на сервер что бы сервером из нее сделать SELECT.
    Может проще LINQ использовать?
    Ответ написан
  • Как правильно составить запрос-исключение SQL?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    Join таблицы саму на себя. Дальше отбор по условию.
    Проверил. Работает.
    create table #table ( id int, parrentid int)
    insert into #table (id, parrentid)
    values
    (1 , 1),
    (2 , 2),
    (3 , 2),
    (4 , 3),
    (5 , 3),
    (6 , 4),
    (7 , 5),
    (8 , 1),
    (9 , 1 )
    
    select * from #TABLE  T 
    left join  #TABLE  T2 ON T.ID=T2.parrentid
    where T2.id is null
    Ответ написан
    Комментировать
  • Как правильно составить SQL запрос?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    У вас немного неправильная логика построения запроса. Сначала сгруппируйте таблицы Order_position и Order_other по GROUP BY Order_id. А потом соединяйте их с заказом.
    Добавил код:
    SELECT O.ID
    	,O.Customer
    	,x.Summ
    	,y.summ
    FROM ORDER O
    LEFT JOIN (
    	SELECT order_id
    		,SUM(Price * Value) AS summ
    	FROM Order_other
    	GROUP BY order_id
    	) x ON O.Id = x.Order_id
    LEFT JOIN (
    	SELECT order_id
    		,SUM(Weight) AS summ
    	FROM Order_position
    	GROUP BY order_id
    	) y ON O.Id = y.Order_id
    Ответ написан
    7 комментариев
  • Как выбрать самые часто упоминаемые тэги из базы данных с помощью SQL?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    select 
    top 100
    tags,
    COUNTposts  
    from 
    (
    select  tags, COUNT( posts ) as COUNTposts 
    from  Posts_Tags
    where  (указываешь диапазон времени)
    group by tags
    ) x
    order by COUNTposts


    Либо убираешь top 100 и пишешь условие для выборки.
    Можно конечно через HAVING еще упростить. Но не знаю есть ли он на MySQL и Postgresql...
    Ответ написан
    Комментировать
  • Как составить SQL запрос?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    Написал вам тестовый кусок с использованием RANK для ваших целей
    CREATE TABLE #products (
    id int,
    name nvarchar(255),
    price money
    )
    insert into #products
    (
    id,
    name,
    price
    )
    values
    (0,'пиво',100),(1,'водка',200),(2,'пиво',150),(3,'пиво',100),(4,'спирт',1000)
    
    
    SELECT 
    	id,
    	name,
    	price
    FROM (
    SELECT id
    	,NAME
    	,price
    	,RANK() OVER (PARTITION BY NAME ORDER BY ID DESC) RNK
    FROM #products ) X
    where X.RNK=1
    Ответ написан
    Комментировать