I have an obsolete 4GL application, which keeps IDs as binary without any encryption.
I have tried simple CAST AS INT, CAST (SUBSTRING(..,3,1000) AS INT) and so to no avail. Can one advise, please?
In the example below binary_source column is a sample data from SQL Server, correct_result one - the result, presented in 4GL application and in between - some of my attempts to convert.
WITH binary_to_convert AS
(
SELECT 0x1841506A00000000 AS binary_source,100005 AS correct_result
UNION ALL SELECT 0x1841506A00000000,100005
UNION ALL SELECT 0x1841506A00000000,100005
UNION ALL SELECT 0x1841506A00000000,100005
UNION ALL SELECT 0x1841506A00000000,100005
UNION ALL SELECT 0x1841706A00000000,100007
UNION ALL SELECT 0x1841706A00000000,100007
UNION ALL SELECT 0x1841906A00000000,100009
UNION ALL SELECT 0x1841906A00000000,100009
UNION ALL SELECT 0x1841706A00000000,100007
UNION ALL SELECT 0x1841706A00000000,100007
UNION ALL SELECT 0x1841706A00000000,100007
UNION ALL SELECT 0x1841706A00000000,100007
UNION ALL SELECT 0x1841706A00000000,100007)
SELECT b.binary_source,
cast(b.binary_source AS INT) AS INT_COLUMN,
CAST(SUBSTRING(b.binary_source,3,1000) AS VARCHAR(MAX)) AS VARCHAR_COLUMN,
CAST(SUBSTRING(b.binary_source,3,1000) AS INT) AS INT_CAST_COLUMN,
b.correct_result
FROM binary_to_convert b
Related
I have a table where one column has repeating values that I need to group. I then want to see if all of the cells within a different column, but within the same grouping match, or more specifically if they don't match.
This is what I have so far.
SELECT Dashboard_Widget_Id, Position ????? AS Is_Different
FROM toolbox.Dashboard_Widget_Sizes
GROUP BY Dashboard_Widget_Id
Never mind. I think I figured it out.
SELECT Dashboard_Widget_Id, CAST(SIGN(COUNT(t.Dashboard_Widget_Id) - 1) AS BIT) AS Is_Different
FROM (
SELECT Dashboard_Widget_Id
FROM toolbox.Dashboard_Widget_Sizes
GROUP BY Dashboard_Widget_Id, Position
) t
GROUP BY Dashboard_Widget_Id
If you wanted to keep the "detail view", here are two approaches using windowing functions:
DECLARE #t5 TABLE (A INT, B INT, C VARCHAR(100))
INSERT INTO #t5 (A,B,C)
SELECT 1,1,'1,2,3,4'
UNION ALL SELECT 1,1,'1,2,3,4'
UNION ALL SELECT 2,1,'1,2,3,4'--
UNION ALL SELECT 2,1,'1,2,3,4'---- Same
UNION ALL SELECT 2,1,'1,2,3,4'--
UNION ALL SELECT 3,1,'1,2,7,4'--
UNION ALL SELECT 3,1,'1,2,3,4'---- Different
UNION ALL SELECT 3,1,'1,2,3,4'--
UNION ALL SELECT 4,1,'1,2,3,4'
--"Alternate Partitions are not equal":
SELECT A,B,C,
CASE WHEN COUNT(*) OVER (PARTITION BY A) <> COUNT(*) OVER (PARTITION BY A,C) THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END IsDifferent
FROM #t5 t
--"DENSE_RANK() OVER Partition > 1":
SELECT
A,B,C,CASE WHEN MAX(D) OVER (PARTITION BY A) > 1 THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END IsDifferent
FROM
(SELECT A,B,C,DENSE_RANK() OVER (PARTITION BY A ORDER BY C) D
FROM #t5 t) a
I have these 3 tables - CodesetList, Rule, Order:
In the first row of the Rule table, if a client ordered any of the CODE_ID under CODESET_ID=12 and any of the CODE_ID under CODESET_ID = 7 on the same service date(DAYS_FROM_Service=0), I want to find the transaction in Order table. Ultimately, if a client orders a combination of two items(Rule table), we want to deny the order according to the rule table.
Sorry, I'm bad at explaining this.
Rule:
CodesetList(note that ABC0274 is under Codeset_ID 9 & 10 and this is expected):
Order:
-- Create CodsetList table
SELECT '7' as CODESET_ID, 'ABC0210' as CODE_ID INTO #CodesetList UNION ALL
SELECT '8','ABC0220' UNION ALL
SELECT '8','ABC0230' UNION ALL
SELECT '8','ABC0240' UNION ALL
SELECT '8','ABC0250' UNION ALL
SELECT '8','ABC0260' UNION ALL
SELECT '9','ABC0270' UNION ALL
SELECT '9','ABC0272' UNION ALL
SELECT '9','ABC0274' UNION ALL
SELECT '9','ABC0273' UNION ALL
SELECT '10','ABC0274' UNION ALL
SELECT '11','ABC0277' UNION ALL
SELECT '12','ABC0330' UNION ALL
SELECT '83','ABC5110' UNION ALL
SELECT '83','ABC5120' UNION ALL
SELECT '83','ABC5130' UNION ALL
SELECT '83','ABC5140'
-- Create Rule table
SELECT '12' as TARGET_CODESET_ID, '7' as DENIAL_CODESET_ID, '2' as DIRECTION_FROM_DOS, '0' as DAYS_FROM_Service INTO #Rule UNION ALL
SELECT '83','7','1','365' UNION ALL
SELECT '7','8','2','0' UNION ALL
SELECT '7','9','2','0'
-- Create Order table
SELECT 'C3340' as ClientID, CAST('2019-10-12' AS DATE) as Service_Date, 'ABC0210' as CODE_ID INTO #Order UNION ALL
SELECT 'C3340',CAST('2019-10-12' AS DATE),'ABC0220' UNION ALL
SELECT 'C3340',CAST('2018-10-23' AS DATE),'ABC0272' UNION ALL
SELECT 'C3340',CAST('2019-10-09' AS DATE),'ABC0220' UNION ALL
SELECT 'C7646',CAST('2019-11-07' AS DATE),'ABC5110' UNION ALL
SELECT 'C7646',CAST('2019-05-07' AS DATE),'ABC0210' UNION ALL
SELECT 'C5376',CAST('2018-12-02' AS DATE),'ABC8411' UNION ALL
SELECT 'C5376',CAST('2018-10-18' AS DATE),'ABC8411' UNION ALL
SELECT 'C5376',CAST('2018-08-06' AS DATE),'ABC8161' UNION ALL
SELECT 'C9873',CAST('2019-01-06' AS DATE),'ABC6517' UNION ALL
SELECT 'C9873',CAST('2019-01-28' AS DATE),'ABC7784' UNION ALL
SELECT 'C9873',CAST('2019-03-05' AS DATE),'ABC8110'
Here's my poor attempt.
It only addresses one of the rules (row 3 from Rule table: Target=7, Denial=8)
And it also ignores the Days_From_Service rule.
SELECT *
FROM (SELECT *
FROM #Order AS o
WHERE o.CODE_ID IN(SELECT CODE_ID FROM #CodesetList WHERE CODESET_ID=7)) AS T
INNER JOIN
(SELECT *
FROM #Order AS o
WHERE o.CODE_ID IN(SELECT CODE_ID FROM #CodesetList WHERE CODESET_ID=8)) AS D ON T.ClientID=D.ClientID AND T.Service_Date=D.Service_Date;
If I execute the code below:
with temp as
(
select 'Test' as name
UNION ALL
select 'TEST'
UNION ALL
select 'test'
UNION ALL
select 'tester'
UNION ALL
select 'tester'
)
SELECT name, COUNT(name)
FROM temp
group by name
It returns the results:
TEST 3
tester 2
Is there a way to have the group by be case sensitive so that the results would be:
Test 1
TEST 1
test 1
tester 2
You need to cast the text as binary (or use a case-sensitive collation).
With temp as
(
select 'Test' as name
UNION ALL
select 'TEST'
UNION ALL
select 'test'
UNION ALL
select 'tester'
UNION ALL
select 'tester'
)
Select Name, COUNT(name)
From temp
Group By Name, Cast(name As varbinary(100))
Using a collation:
Select Name Collate SQL_Latin1_General_CP1_CS_AS, COUNT(name)
From temp
Group By Name Collate SQL_Latin1_General_CP1_CS_AS
You can use an case sensitive collation:
with temp as
(
select 'Test' COLLATE Latin1_General_CS_AS as name
UNION ALL
select 'TEST'
UNION ALL
select 'test'
UNION ALL
select 'tester'
UNION ALL
select 'tester'
)
SELECT name, COUNT(name)
FROM temp
group by name
Simply:
SELECT count(*), CAST(lastname as BINARY) AS lastname_cs
FROM names
GROUP BY lastname_cs;
In MySQL/MariaDB, if you don't want to use collations or casting to binary, just use:
SELECT MAX(name), COUNT(name)
FROM (
select 'Test' as name
UNION ALL
select 'TEST'
UNION ALL
select 'test'
UNION ALL
select 'test'
UNION ALL
select 'tester'
UNION ALL
select 'tester'
) as tmp
group by MD5(name)
This works on my case:
SELECT BINARY example FROM table GROUP BY BINARY example;
I have a table with two columns like this:
A 1
B 2
C 3
D 4
E 5
etc.
I want to get them into one column, with each column's data in alternate rows of the new column like this:
A
1
B
2
C
3
D
4
E
5
etc.
I would use a UNION ALL but here is the UNPIVOT alternative:
CREATE TABLE #Table1(letter VARCHAR(10),Id VARCHAR(10))
INSERT INTO #Table1(letter ,Id )
SELECT 'A',1 UNION ALL
SELECT 'B',2 UNION ALL
SELECT 'C',3 UNION ALL
SELECT 'D',4 UNION ALL
SELECT 'E',5
SELECT [value]
FROM #Table1
UNPIVOT
(
[value] FOR [Column] IN ([Id], [letter])
) UNPVT
DROP TABLE #Table1;
The tricky part is the data in alternate rows
select col2
from
( select col1, 1 as flag, col1 from tab
union all
select col1, 2, col2 from tab
) as dt
order by col1, flag
But why do you try to do this at all?
Try this :
WITH CTE AS
(
SELECT Col1Name Name,(ROW_NUMBER() OVER(ORDER BY(SELECT NULL))) RN
FROM TableName
UNION
SELECT Col2Name Name,(ROW_NUMBER() OVER(ORDER BY(SELECT NULL)))+1 RN
FROM TableName
)
SELECT Name
FROM CTE
ORDER BY RN
CREATE TABLE #Table1(Value VARCHAR(10),Id VARCHAR(10))
INSERT INTO #Table1(Value ,Id )
SELECT 'A',1 UNION ALL
SELECT 'B',2 UNION ALL
SELECT 'C',3 UNION ALL
SELECT 'D',4 UNION ALL
SELECT 'E',5
;WITH _CTE (Name) AS
(
SELECT Value [Name]
FROM #Table1
UNION ALL
SELECT Id [Name]
FROM #Table1
)
SELECT * FROM _CTE
I need alias union of three query like this:
select * from
(
select * from A
union
select * from B
union
select * from c)t1
My code appear error.
I don't know how solve it.
Please help me
First, instead of using SELECT *, specifically name your columns; that's probably where your error lies. One or more of your tables (A, B, or C) probably has more or less columns than the others.
SELECT col1, col2
FROM ( SELECT col1, col2
FROM A
UNION
SELECT col1, col2
FROM B
UNION
SELECT col1, col2
FROM c
) t1
If that doesn't fix it, then post the error message you received, and the RDBMS you are using.