How to get the total value for two records from msSQL

catId DealId 1 668 2 668 3 669 1 669 3 671 11 671 12 671 7 669 12 672 13 673 

Suppose this is a table. If I as input of two values ​​for catId , the request should return all records containing the same DealId .

0
source share
4 answers

Version 1: I added an example of exact division

This operation is called relational division. In this case, Table1 (CatID, DealID) is a dividend, and Table2 (CatID) is a dividend. The result (quotient) of the operation Table1(CatID, DealID) DIVIDED BY Table2(CatID) represents all DealIDs (Table 1) that have the same CatIDs (Table 2).

Something is not very clear to me: do you need exact division or division with remainder?

Take a look at this article article written by Joe Selco.

(Revision1) An example for exact division (my values ​​from the table (CatID, DealID) are different, explanations and risks are given below):

 DECLARE @Table1 TABLE ( DealID INT NOT NULL ,CatID INT NOT NULL ,PRIMARY KEY(DealID, CatID) ); INSERT @Table1 (DealID, CatID) SELECT src.DealID, src.CatID FROM ( SELECT 1 CatID, 668 DealID UNION ALL SELECT 2 CatID, 668 DealID UNION ALL SELECT 2 CatID, 669 DealID UNION ALL SELECT 1 CatID, 669 DealID UNION ALL SELECT 2 CatID, 671 DealID UNION ALL SELECT 11 CatID, 671 DealID UNION ALL SELECT 12 CatID, 671 DealID UNION ALL SELECT 11 CatID, 672 DealID UNION ALL SELECT 12 CatID, 672 DealID UNION ALL SELECT 13 CatID, 673 DealID ) src; --Test1 DECLARE @Table2 TABLE ( CatID INT NOT NULL PRIMARY KEY ); INSERT @Table2 VALUES (1); INSERT @Table2 VALUES (2); SELECT CatID, DealID FROM @Table1 ORDER BY DealID; SELECT * FROM @Table2 ORDER BY CatID; SELECT a.DealID--, CHECKSUM_AGG( CHECKSUM(HASHBYTES('sha1',CAST(a.CatID AS VARCHAR(11)))) ) Agg FROM @Table1 a GROUP BY a.DealID HAVING CHECKSUM_AGG( CHECKSUM(HASHBYTES('sha1',CAST(a.CatID AS VARCHAR(11)))) ) = ( SELECT CHECKSUM_AGG( CHECKSUM(HASHBYTES('sha1',CAST(b.CatID AS VARCHAR(11)))) ) FROM @Table2 b ); --End of Test1 --Test2 DELETE @Table2; INSERT @Table2 VALUES (11); INSERT @Table2 VALUES (12); SELECT a.DealID--, CHECKSUM_AGG( CHECKSUM(HASHBYTES('sha1',CAST(a.CatID AS VARCHAR(11)))) ) Agg FROM @Table1 a GROUP BY a.DealID HAVING CHECKSUM_AGG( CHECKSUM(HASHBYTES('sha1',CAST(a.CatID AS VARCHAR(11)))) ) = ( SELECT CHECKSUM_AGG( CHECKSUM(HASHBYTES('sha1',CAST(b.CatID AS VARCHAR(11)))) ) FROM @Table2 b ); --End of Test2 

Explanations:

  • This subquery SELECT CHECKSUM_AGG( CHECKSUM(HASHBYTES('sha1',CAST(b.CatID AS VARCHAR(11)))) ) FROM @Table2 b generates an identifier for all CatID values ​​from the divisor table (Table 2 b).
  • In the basic query, the records from the dividend table will be grouped (table 1 a): GROUP BY a.DealID and for each a.DealID value, it generates an identifier for all values ​​from the CatID field using hash functions: CHECKSUM_AGG( CHECKSUM(HASHBYTES('sha1',CAST(a.CatID AS VARCHAR(11)))) ) .

Risks:

  • Hashing functions can sometimes create conflicts (especially older hash functions: CHECKSUM [_AGG]).
  • To reduce the risk of collisions, I use the HASHBYTES function.
  • From my tests (somehow this problem is old for me), I never encountered collisions, but never said never.
  • THE DECISION IS PROVIDED "AS IS" WITHOUT WARRANTY.
  • For production, use one of Celko's solutions.
+2
source

Try this (hopping what you need):

 SELECT DealId, catId, count(catId) AS tot FROM your_table WHERE catId = your_cat1 OR catId = your_cat2 GROUP BY DealId HAVING tot > 1 
0
source

SQL statement

 ;WITH CatIDs (catID) AS ( SELECT 1 UNION ALL SELECT 2 ) SELECT mt.* FROM MyTable mt INNER JOIN CatIDs cid ON cid.catID = mt.catID INNER JOIN ( SELECT mt.DealID FROM MyTable mt INNER JOIN CatIDs ids ON ids.catID = mt.catID GROUP BY mt.DealID HAVING COUNT(mt.DealID) = (SELECT COUNT(*) FROM CatIDs) ) did ON did.DealID = mt.DealID 

Test script

 ;WITH MyTable (catID, DealID) AS ( SELECT 1, 668 UNION ALL SELECT 2, 668 UNION ALL SELECT 3, 669 UNION ALL SELECT 1, 669 UNION ALL SELECT 3, 671 UNION ALL SELECT 11, 671 UNION ALL SELECT 12, 671 UNION ALL SELECT 7, 669 UNION ALL SELECT 12, 672 UNION ALL SELECT 13, 673 ) , CatIDs (catID) AS ( SELECT 1 UNION ALL SELECT 2 ) SELECT mt.* FROM MyTable mt INNER JOIN CatIDs cid ON cid.catID = mt.catID INNER JOIN ( SELECT mt.DealID FROM MyTable mt INNER JOIN CatIDs ids ON ids.catID = mt.catID GROUP BY mt.DealID HAVING COUNT(mt.DealID) = (SELECT COUNT(*) FROM CatIDs) ) did ON did.DealID = mt.DealID 
0
source

I do not understand your question, hope the syntax helps you. CREATION PROCEDURE [spName]

  @Parameter1 INT, @Parameter2 INT AS BEGIN SELECT * FROM TableName WHERE DealId FROM TableName WHERE catId=@Parameter1 AND DealId FROM TableName WHERE catId=@Parameter2 END 
0
source

All Articles