I have a table that contains column names like this;
+--------------------------------------------------------------------+-----------+
| BankTable | |
+--------------------------------------------------------------------+-----------+
| Id | BANK1 | BANK2 | BRANCH1 | BRANCH2 | IBAN1 | IBAN2 |
+----+-----------+-----------+-------------+-------------+-----------+-----------+
| 1 | BANK1_ID1 | BANK2_ID1 | BRANCH1_ID1 | BRANCH2_ID1 | IBAN1_ID1 | IBAN2_ID1 |
+----+-----------+-----------+-------------+-------------+-----------+-----------+
| 2 | BANK1_ID2 | BANK2_ID2 | BRANCH1_ID2 | BRANCH1_ID2 | IBAN1_ID2 | IBAN2_ID2 |
+----+-----------+-----------+-------------+-------------+-----------+-----------+
How can i write a query that returns the result like this;
+------------------------------------------+
| BANK |
+------------------------------------------+
| ID | BANK | BRANCH | IBAN |
+----+-----------+-------------+-----------+
| 1 | BANK1_ID1 | BRANCH1_ID1 | IBAN1_ID1 |
+----+-----------+-------------+-----------+
| 2 | BANK2_ID2 | BRANCH1_ID2 | IBAN2_ID2 |
+----+-----------+-------------+-----------+
P.s: I am writing select query by Id column. BTW query result contains one row every time.
Any help appreciated.
SOLUTION
I don't know if it's good approach but i solved this by based on #Giorgos Betsos answer. Here is how i fixed this problem.
SELECT BANK, BRANCH, IBAN
FROM (
SELECT BANK1, BANK2, BRANCH1, BRANCH2, IBAN1, IBAN2
FROM BankTable
WHERE ID = your_id_here
) AS src
UNPIVOT (
BANK FOR Col IN(BANK1, BANK2)
) AS unpvt1
UNPIVOT (
BRANCH FOR Col1 IN(BRANCH1, BRANCH2)
) AS unpvt2
UNPIVOT (
IBAN FOR Col2 IN(IBAN1, IBAN2)
) AS unpvt3
WHERE RIGHT(Col, 1) = RIGHT(Col1, 1)
AND RIGHT(Col, 1) = RIGHT(Col2, 1)
You can use UNPIVOT for this:
SELECT Bank
FROM (
SELECT Id, BANK1, BANK2, BANK3, BANK4, BANK5
FROM BankTable
WHERE id = 1) AS src
UNPIVOT (
Bank FOR Col IN([BANK1], [BANK2], [BANK3], [BANK4], [BANK5])) AS unpvt
Demo here
If number of column is more, then you can use a dynamic sql query as below:
Query
declare #sql as varchar(max);
select #sql =stuff(
(select 'union all select [' + column_name + '] as Bank
from BankTable where Id = 1 '
from information_schema.columns
where table_name = 'BankTable'
and column_name like 'BANK[0-9]%'
for xml path('')), 1, 9, '');
execute(#sql);
Result
+-----------+
| Bank |
+-----------+
| BANK1_ID1 |
| BANK2_ID1 |
| BANK3_ID1 |
| BANK4_ID1 |
| BANK5_ID1 |
+-----------+
Related
I'm trying to pivot a table from the format
| ID | access date |
--------------
| 1 | 08.10|
| 1 | 08.10|
| 4 | 08.10|
| 2 | 02.09|
To
|ID | 02.09 | 03.09 | 04.09 | ....
| 1 | 4 | 0 | 2 |
| 2 | 1 | 2 | 5 |
| 3 |
.
.
.
I've tried using the PIVOT function but since I have a lot of different dates I don't want to type out the query
SELECT *
FROM (
SELECT [Sequence of events] as ID
,[Submission Date] as access_date
FROM [database_name].[dbo].[Event Logging]
) AS SOURCE_TABLE
PIVOT( SUM(ID) for access_date IN ("08.01", "09.01", "10.01"....)
) as pvt_table
I'm very new to SQL so I'd appreciate some insight into how to solve this problem.
This is not answer about solving problem in your way but it is about solving it another way.
What i would do is create 2 tables. First one would be called DATE_DB where i would store DATEID and DATE and it would look like this:
| DATEID | DATE |
| 1 | 01.01|
| 2 | 02.02|
....
Then in second table I store data like this:
| ID | DATEID | VALUE |
| 1 | 2 | 10 |
| 2 | 2 | 3 |
| 3 | 3 | 4 |
| 4 | 2 | 5 |
So in second table column ID is used only for primary key and has nothing to do but with tables like this and JOIN command you can use it like this:
SELECT DATE_DB.DATE, SECONDTABLE.VALUE
FROM SECONDTABLE
LEFT JOIN DATE_DB ON SECONDTABLE.DATEID = DATE_DB.DATE
ORDER BY DATE_DB.DATE
which will display result like this:
| DATE | VALUE |
| 02.01 | 10 |
| 02.01 | 3 |
| 02.01 | 5 |
| 03.01 | 4 |
Try it out like this, you need dynamic sql, note script isn't tested out, also when you naming your columns try not to have space, ether use CamelCase or underscore to separate words
And last thing, this is for SQL-Server, as you didn't tag anything and your code looks like sql-server
declare #cols nvarchar(max)
select #cols = STUFF((SELECT DISTINCT ',' + QUOTENAME([Submission Date])
from [database_name].[dbo].[Event Logging]
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
declare #sql nvarchar(max);
set #sql = '
SELECT *
FROM (
SELECT [Sequence of events] as ID
,[Submission Date] as access_date
FROM [database_name].[dbo].[Event Logging]
) AS SOURCE_TABLE
PIVOT( SUM(ID) for access_date IN (' + #cols + ')
) as pvt_table';
-- print (#sql)
execute (#sql)
I have a table with name "table_name" approximately like this
+----+-----------+
| ID | title |
| 1 | title 1 |
| 2 | title 2 |
| ...| ......... |
| ...| ......... |
| n | title n |
+----+-----------+.
And I need a query that returns this result
+------+-----------+
| n+1 | title 1 |
| n+1 | title 2 |
| ... | ......... |
| ... | ......... |
| n+1 | title n |
+------+-----------+
(n+1 is select max(ID) from table_name)
how can I do that?
Simply add a sub-query to the select list:
select (select max(ID) + 1 from tablename), title
from tablename
Window function
SELECT MAX(ID) OVER() + 1, title
FROM table_name
You can select this max ID to a variable, and then simply use it in your select:
DECLARE #maxId INT = (SELECT MAX(ID) FROM [dbo].[table1]);
SELECT #maxId, t.title, t.column2, t.column3 ... from [dbo].[table2] t
For Mysql
select (1+max(ID)) as ID ,title
from table_name;
After trying it myself for some hours now I need to ask for help. I only did some basic SQL until now.
I want to solve the following:
(I have translated a couple of things for you to understand the context)
I have three tables:
Workers (Mitarbeiter in German - mitID)
| mitID | Name | FamName | DOB | abtIDref |
|-------|--------|---------|------------|----------|
| 1 | Frank | Sinatra | 12.12.1915 | 1 |
| 2 | Robert | Downey | 4.4.1965 | 2 |
INFO: abtIDref is an 1:n relation for the Workplace, but not involved here
Skills (Faehigkeiten in German - faeID)
| faeID | Descr | time | cost |
|-------|-------|------|------|
| 1 | HV | 2 | 0 |
| 2 | PEV | 1 | 0 |
| 3 | Drive | 8 | 250 |
| 4 | Nex | 20 | 1200 |
Link-List
| linkID | mitIDref | feaIDref | when |
|--------|----------|----------|------------|
| 1 | 2 | 1 | 27.07.2014 |
| 2 | 2 | 2 | 01.01.2016 |
| 3 | 2 | 3 | 20.01.2016 |
| 4 | 1 | 3 | 05.06.2015 |
| 5 | 1 | 4 | 02.11.2015 |
The desired result is:
| mitID | Name | FamName | DOB | abtIDref | HV | PEV | Drive | Nex |
|-------|--------|---------|------------|----------|-----------|------------|------------|------------|
| 1 | Frank | Sinatra | 12.12.1915 | 1 | | | 05.06.2015 | 02.11.2015 |
| 2 | Robert | Downey | 4.4.1965 | 2 | 27.7.2014 | 01.01.2016 | 20.01.2015 | |
Alternative it could be:
| mitID | Name | FamName | DOB | abtIDref | HV | PEV | Drive | Nex |
|-------|--------|---------|------------|----------|----|-----|-------|-----|
| 1 | Frank | Sinatra | 12.12.1915 | 1 | | | x | x |
| 2 | Robert | Downey | 4.4.1965 | 2 | x | x | x | |
The goal is that users/admins can add up new skills and someone can see on this resultlist, if a person has this skill.
What did i try:
I've come across multiple examples of dynamic SQL and the pivot function, but I don't know how to use it in my case, because I don't run a function like AVG() or MIN().
I tried it like this:
DECLARE #columns AS VARCHAR(MAX);
DECLARE #sql AS VARCHAR(MAX);
select #columns = substring((Select DISTINCT ',' + QUOTENAME(faeID) FROM mdb_Fähigkeiten FOR XML PATH ('')),2, 1000);
SELECT #sql = 'SELECT * FROM mdb_Mitarbeiter
PIVOT
(
MAX(Value)
FOR mitID IN( ' + #columns + ' )
);';
execute(#sql);
And a second approach was:
declare #collist nvarchar(max)
SET #collist = stuff((select distinct ',' + QUOTENAME(Question)
FROM #t1 -- your table here
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')
select #collist
declare #q nvarchar(max)
set #q = '
select *
from (
select
Vorname, Bezeichnung, faeIDref
from (
select #t1.*, #t2.Answer, #t2.parent
from #t1
inner join #t2 on #t1.QID = #t2.QID
) as x
) as source
pivot (
max(Answer)
for Question in (' + #collist + ')
) as pvt
'
exec (#q)
But TBH I don't get the functions found.
I hope you can provide me with some guidance what I have to change (or even if I can) achieve this.
I believe the query below is what you are looking for. Adjust the column and table names as needed to fit your database.
DECLARE #sql AS NVARCHAR(MAX)
DECLARE #cols AS NVARCHAR(MAX)
SELECT #cols= ISNULL(#cols + ',','') + QUOTENAME(Descr)
FROM Faehigkeiten ORDER BY faeID
SET #sql = N'
SELECT mitID, Name, FamName, DOB, abtIDref, ' + #cols + '
FROM (
SELECT mitID, Name, FamName, DOB, abtIDref, [when], descr
FROM Mitarbeiter m
JOIN [Link-List] l ON m.mitID = l.mitIDref
JOIN Faehigkeiten f ON f.faeID = l.feaIDref
) a
PIVOT(MAX([when]) FOR descr IN (' + #cols + ')) p'
EXEC sp_executesql #sql
I have a table with a varchar(max). I would like to know if it's possible to get all rows that contains any substring from a list of it.
I know that for one value I can use like 'AAA%', but I don't know if like has any way to say something like where IN().
Something like this:
select * from TableA where
TableA.Field1 contains any (select Fild1 from TableB where field2 > 5);
Where TableA.Field 1 and TableB.Field1 are varchar(max).
Thank you so much.
select * from TableA
where exists (select 1 from TableB
where TableA.Field1 like '%' + TableB.Fild1 + '%'
and TableB.field2 > 5)
SQL Server includes the CONTAINS function so something like this will work fine.
SELECT *
FROM TableA
JOIN TableB ON CONTAINS(TableA.Field1, TableB.Fild1) AND TableB.field2 > 5
You may need to adjust for your requirements.
Here is the documentation on contains
https://msdn.microsoft.com/en-us/library/ms187787.aspx
You can use a dynamic sql query.
Query
declare #query varchar(max)
select #query = 'select * from t1 where ' +
STUFF
(
(
select ' OR col1 like ''' + col1 + '%'''
from t2
for xml path('')
),
1,4,'');
execute(#query);
Example
Table - t1
+----+-------+
| id | col1 |
+----+-------+
| 1 | AAAAA |
| 2 | BBBBB |
| 3 | CCCCC |
| 4 | DDDDD |
| 5 | EEEEE |
+----+-------+
Table - t2
+------+
| col1 |
+------+
| AA |
| BB |
| CC |
+------+
Output
+----+-------+
| id | col1 |
+----+-------+
| 1 | AAAAA |
| 2 | BBBBB |
| 3 | CCCCC |
+----+-------+
I have the following dataset on a sql database
----------------------------------
| ID | NAME | AGE | STATUS |
-----------------------------------
| 1ASDF | Brenda | 21 | Single |
-----------------------------------
| 2FDSH | Ging | 24 | Married|
-----------------------------------
| 3SDFD | Judie | 18 | Widow |
-----------------------------------
| 4GWWX | Sophie | 21 | Married|
-----------------------------------
| 5JDSI | Mylene | 24 | Singe |
-----------------------------------
I want to query that dataset so that i can have this structure in my result
--------------------------------------
| AGE | SINGLE | MARRIED | WIDOW |
--------------------------------------
| 21 | 1 | 1 | 0 |
--------------------------------------
| 24 | 1 | 1 | 0 |
--------------------------------------
| 18 | 0 | 0 | 1 |
--------------------------------------
And the status column can be dynamic so there will be more columns to come.
Is this possible?
Since you are using SQL Server, you can use the PIVOT table operator like this:
SELECT *
FROM
(
SELECT Age, Name, Status FROM tablename
) AS t
PIVOT
(
COUNT(Name)
FOR Status IN(Single, Married, Widow)
) AS p;
SQL Fiddle Demo
To do it dynamically you have to use dynamic sql like this:
DECLARE #cols AS NVARCHAR(MAX);
DECLARE #query AS NVARCHAR(MAX);
select #cols = STUFF((SELECT distinct ',' +
QUOTENAME(status)
FROM tablename
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
, 1, 1, '');
SELECT #query = '
SELECT *
FROM
(
SELECT Age, Name, Status FROM tablename
) AS t
PIVOT
(
COUNT(Name)
FOR Status IN( ' +#cols + ')
) AS p;';
execute(#query);
Updated SQL Fiddle Demo