Get all values in temp table with sql pivot - sql

I have this data at temp table
Country |City
-----------|-------------
Philippines|Mandaluyong
Philippines|Quezon
Philippines|Aurora
America |Example
America |Example2
And I want to display using pivot like this
Philippines|America
-----------|-------------
Aurora |Example
Mandaluyong|Example2
Quezon
But currently, I got this only
Philippines|America
-----------|-------------
Quezon|Example2
Here is my code below. Did I miss something?
DECLARE #TempTable TABLE (Country VARCHAR(MAX), City VARCHAR(MAX))
INSERT INTO #TempTable (Country, City)
SELECT 'Philippines' AS Country, 'Mandaluyong' AS City
UNION ALL
SELECT 'Philippines', 'Quezon'
UNION ALL
SELECT 'Philippines', 'Aurora'
UNION ALL
SELECT 'America', 'Example'
UNION ALL
SELECT 'America', 'Example2'
SELECT * FROM #TempTable
SELECT Philippines, America
FROM
(
SELECT Country, city
FROM #TempTable
)temp
PIVOT
(
MAX (City)
For Country in (Philippines, America)
)piv

The result set was grouping by the Country field, as a result there would be one row per Country, which is what gave the results the way you have.
On including a grouping column (ie numbering the records by country in a row_number) function you would get the results you expect
DECLARE #TempTable TABLE (Country VARCHAR(MAX), City VARCHAR(MAX))
INSERT INTO #TempTable (Country, City)
SELECT 'Philippines' AS Country, 'Mandaluyong' AS City
UNION ALL
SELECT 'Philippines', 'Quezon'
UNION ALL
SELECT 'Philippines', 'Aurora'
UNION ALL
SELECT 'America', 'Example'
UNION ALL
SELECT 'America', 'Example2'
SELECT * FROM #TempTable
SELECT Philippines, America
FROM
(
SELECT row_number() over(partition by Country order by city) as rnk,Country, city
FROM #TempTable
WHERE country in ('Philippines','America')
)temp
PIVOT
(
MAX (City)
For Country in (Philippines, America)
)piv
https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=212381456098cd4fd858de3e01257067

Related

SQL remove duplicate rows when counting

I have a select statement using count and since I am counting the rows instead of returning them how do I make sure that I do not get a duplicate value on a column?
For Example
_table_
fName someField
Eric data
Kyle mdata
Eric emdata
Andrew todata
I want the count to be 3 because Eric is duplicated, is there a way to do that? My select is:
Select Count(*) From _table_ INTO :var
Thanks,
SELECT Count(DISTINCT fName) From _table_ INTO :var
It will count number of distinct elements from fName column.
This will do the Job Select Count(distinct fnmae) From _table_ INTO :var
Try SELECT Count(DISTINCT fName) From _table_ INTO :var
You could select the count of DISTINCT first names:
declare #table table (fname varchar(20), someField varchar(20))
insert into #table (fname, someField)
select 'Eric', 'data'
union select 'Kyle', 'mdata'
union select 'Eric', 'emdata'
union select 'Andrew', 'todata'
-- returns 4, because there are 4 rows in the table
select count(*) from #table
-- returns 3, because there are 3 rows with distinct first names
select count(*) from (select distinct fname from #table) firstNames

SQL Query to Retrieve data by comparing column name to a particular string

I have a SQL Table consisting of customer, transaction and store. Store has 3 values (X,Y,Z)
I want to retrieve customers who shopped at particular store, so I used this query
select distinct customer from TABLE group by store.
However, now I want the customer details who shopped at 2 stores (X,Y) (Y,Z) (Z,X) and also (X,Y,Z).
When I use
select distinct customer from TABLE where store='X'
it gives 0 results in oracle SQL Developer
How to proceed from here?
Try following:
Select Customer From
(
Select Customer,Store from TableName group by Store,Customer
)tbl
Group By Customer Having COUNT(Customer)>=2 Order By Customer
Edit:
Declare #MainTable table
(
Customer varchar(222),Store varchar(2222)
)
Insert Into #MainTable
Select 'C1','X'
Union All
Select 'C1','Y'
Union All
Select 'C1','X'
Union All
Select 'C2','X'
Union All
Select 'C2','Y'
Union All
Select 'C2','Z'
Union All
Select 'C3','X'
Union All
Select 'C3','Z'
Union All
Select 'C4','X'
Union All
Select 'C4','Y'
Declare #temp table
(
Customer varchar(200)
)
Insert Into #temp
Select Customer From
(
Select Customer,Store from #MainTable group by Store,Customer
)tbl
Group By Customer Having COUNT(Customer)>=2 Order By Customer
Declare #Customer_Store table
(
Customer varchar(200),
Stores varchar(200)
)
DECLARE #Stores varchar(10)
Declare #Customer varchar(256)
While((Select COUNT(*) From #temp)>0)
Begin
Set #Customer=(Select Top 1 Customer From #temp)
Select #Stores=coalesce(#Stores + ',','') + Store From
#MainTable Where Customer=#Customer
Group By Store
Order By Store
Insert Into #Customer_Store Select #Customer,#Stores
Delete From #temp Where Customer=#Customer
Set #Stores=null
End
Select Cast(COUNT(Customer) as Varchar(5))+' Customers shopped at Store ('+Stores+')' CustomerDetail From #Customer_Store
Group By Stores
Output:
2 Customers shopped at Store (X,Y)
1 Customers shopped at Store (X,Y,Z)
1 Customers shopped at Store (X,Z)
select distinct customer from tablename group by customer ,store having count(stores)>2
sorry....you can try like this
"select customer,store from table_name group by customer ,store having count(customer)>=1 order by customer asc"
i hope this is correct.
I think you should use something like GROUP_CONCAT in MySQL.
Here you can find how you can emulate it in Oracle
For example for Oracle 11g R2 you can use LISTAGG:
SQLFiddle demo
SELECT customer,
LISTAGG(store, ',') WITHIN GROUP (ORDER BY store)
AS STORES
FROM
(select distinct customer,store from t) t1
GROUP BY customer;

Union two different tables with a primary ID field

I have two tables
MD_Master (Medical checks)
Id
...
CD_Personal (Personal Checks)
Id
...
Each fieldname in both tables are different names, types, and data.
However, each has a Primary Key Id, and can potentially conflict with eath other.
i.e. Id 101 can exist in both MD_Master and CD_Personal
I would like to create a view combing both tables (combining MD_Medical and CD_Personal Id fields) but I don't know how to handle the Ids.
I would like the view to have a Numeric(19,0) for Id.
Would it be possible to select and do a union of these two diffeent tables and create a unique ID?
Thanks
It is not exactly clear what you are trying to do here but you can create an identifier on each row similar to this:
SELECT Id, 'M' as tbl
FROM MD_Master
UNION ALL
SELECT Id, 'P' as tbl
FROM CD_Personal
This will allow you to distinguish between each row, by seeing which table the record came from. Then if you have records with the same ID you will know what table is came from.
You can try something like this:
declare #medical table(id int, checks varchar(10))
declare #personal table(id int, checks varchar(10))
insert into #medical
select 1, 'abc1'
union
select 2, 'abc2'
insert into #personal
select 1, 'abc1'
union
select 2, 'abc22'
;WITH CTE AS (
select *, 'M' As Src from #medical
union
select *, 'P' As Src from #personal
)
SELECT checks, src, ROW_NUMBER() over (order by checks, id) new_id FROM CTE
In your case:
SELECT checks, src, ROW_NUMBER() over (order by [checks], id) new_id
FROM
(
SELECT id, [Medical checks] Checks, 'M' as Src FROM MD_Master
UNION ALL
SELECT id, [Personal checks] Checks, 'P' as Src FROM CD_Personal
)
Perhaps you can concatenate the ID with something to stop conflict? You can parse it back out again if necessary, i.e....
SELECT CONVERT(varchar, ID) + 'MD', FirstName, LastName, DOB FROM MD_Master
UNION
SELECT CONVERT(varchar, ID) + 'CD', FirstName, LastName, DOB FROM CD_Personal
What are you trying to do with the data afterwards?

Select multi identity values for multiple inserts along with columns not inserted into the table

I am inserting only 1 column into TempId table i.e name from a select statement
How do i get corresponding orderId for the identity column.
INSERT INTO tempId
output inserted.ID
Select name FROM (
select 'erty' as name, 1 as orderid union
select 'rth' as name, 2 as orderid union
select 'yt' as name, 3 as orderid union
select '345' as name, 4 as orderid union
select 'rtyu' as name, 5 as orderid union
select 'uio' as name, 6 as orderid union
select 'yu' as name, 7 as orderid union
select 'xzf' as name, 8 as orderid
) as a
PS Note: SELECT with union is only done for sample query. Ideally I will get things from another table.
You put the id and any other fields you need to use later in a table varaiable or temp table by using the OUTPUT clause
DECLARE #MyTableVar table( ID int, orderid int);
INSERT mytable (field1, orderID)
OUTPUT INSERTED.ID, INSERTED.OrderID
INTO #MyTableVar
SELECT FIELD2, orderid FROM Myothertable
Now you have the data available in #MyTableVar to do inserts to child tables or the other work you wanted to do.
just arrange the columns:
create table #tempID( id int, name varchar(50))
INSERT INTO #tempID (name, id)
output inserted.ID
Select name, orderid FROM (
select 'erty' as name, 1 as orderid union
select 'rth' as name, 2 as orderid union
select 'yt' as name, 3 as orderid union
select '345' as name, 4 as orderid union
select 'rtyu' as name, 5 as orderid union
select 'uio' as name, 6 as orderid union
select 'yu' as name, 7 as orderid union
select 'xzf' as name, 8 as orderid
) as a
This is an example on inserting values directly. If there are no triggers you can get ##IDENTITY.
insert into [FTSwordDef] ([word]) values ('value')
select scope_identity();
Scope_identity (and the evil ##) will only return the last iden. If you are inserting multiple rows then I think you would need to loop in a SP and build up the list of iden. Iden is created by the insert and is not available IN the insert to my knowledge.
If you held a tablock on the the insert and retrieved the last identity and how many rows were inserted then in theory the insert got the last x inden values. If your insert was sorted you would know what iden went with which row.

CASE condition and how to code it?

I am creating a column in a new table( Table B) called Number of different locations. This column is derived from two columns in a Table A - Customer and Location.
Sample Data from Table A .
Customer Location
Mr James Smith Los Angeles
Mr David Jones London
Mr James Smith Paris
So the pseudo code ?
[Number of Different Locations] =
CASE
When Customer has more than one location ( count greater than 1 of for distinct customer)
Then populate those entries as 'Y'
Else 'N'
Now I have tried a few ways to code the 1st condition but it does not work .
CASE
When EXISTS ( select distinct customer, count ( Location ) from Table B
group by customer)
then 'Y'
Else 'N'
What am I doing wrong ? All the values are coming out in resultant table as 'Y'
SELECT Customer, Location, [Number of different locations] =
CASE
When EXISTS ( select distinct customer, count ( Location ) from Table B
group by customer
having count(location)>1)
then 'Y'
Else 'N'
END
FROM [Table]
you didn't specify "Having > 1"
You don't really need a separate subselect for that. This can be handled entirely within a GROUP BY clause and using the count of locations to determine if there are multiple locations.
SELECT Customer
, MultipleLocations =
CASE WHEN COUNT(Location) > 1
THEN 'Y'
ELSE 'N'
END
FROM YourTable
GROUP BY
Customer
Should your table contain multiple records for a customer with the same location, you can add a DISTINCT clause to accomodate for this.
SELECT Customer
, MultipleLocations =
CASE WHEN COUNT(DISTINCT Location) > 1
THEN 'Y'
ELSE 'N'
END
FROM YourTable
GROUP BY
Customer
Maybe this will help did it in another way:
DECLARE #tbl TABLE
(
Customer VARCHAR(100),
Location VARCHAR(100)
)
INSERT INTO #tbl
SELECT 'Mr James Smith','Los Angeles'
UNION ALL
SELECT 'Mr David Jones','London'
UNION ALL
SELECT 'Mr James Smith','Paris'
;WITH CTE AS
(
SELECT
COUNT(*) OVER(PARTITION BY tbl.Customer) AS NbrOf,
tbl.Customer,
tbl.Location
FROM
#tbl AS tbl
)
SELECT
CTE.Customer,
CTE.Location,
(
CASE
WHEN CTE.NbrOf>1
THEN 'Y'
ELSE 'N'
END
) AS newColumn
FROM
CTE
WITH TableA
AS
(
SELECT *
FROM (
VALUES ('Mr James Smith', 'Los Angeles'),
('Mr David Jones', 'London'),
('Mr James Smith', 'Paris')
) AS T (Customer, Location)
),
TableACustomerTallies
AS
(
SELECT Customer, COUNT(DISTINCT Location) AS Tally
FROM TableA
GROUP
BY Customer
)
SELECT Customer,
'Y' AS HasMultipleLocations
FROM TableACustomerTallies
WHERE Tally > 1
UNION
SELECT Customer,
'N' AS HasMultipleLocations
FROM TableACustomerTallies
WHERE Tally <= 1;