Joining two selects - different column names - sql-server

I need to build a SELECT statement showing all columns for JV1 - JV6.
How would I go about getting JV2, JV3, etc populated?
SELECT
Id as [JV1],
vp_pct as [JV1 Per],
vl_role as [JV1 Role],
[status] as [JV1 Status]
FROM era_project_allications_m
WHERE era_project_allications_m.jv_row_id = '1'
UNION ALL
SELECT
Id as [JV2],
vp_pct as [JV2 Per],
vl_role as [JV2 Role],
[status] as [JV2 Status]
FROM era_project_allications_m
WHERE era_project_allications_m.jv_row_id = '2'
I need the results to display columns containing the JV1, JV2 information.
Thanks for any advice!

Join and union are 2 different things. You can't have different column names in union but you can add a column that will hold the source table name (hard coded) to help you understand where the row comes from:
SELECT
Id,
vp_pct,
vl_role,
[status],
'1' as sourceId
FROM era_project_allications_m
WHERE jv_row_id = '1'
UNION ALL
SELECT
Id,
vp_pct,
vl_role,
[status],
'2'
FROM era_project_allications_m
WHERE jv_row_id = '2'
though based on your sample code you might just want to do this:
SELECT
Id,
vp_pct,
vl_role,
[status],
jv_row_id as sourceId
FROM era_project_allications_m
WHERE jv_row_id IN('1', '2'...'n')

I Figured this one out.
I simply used 6 select statements, giving them each an aliases and a unique ID (project ID as Select_1_ID, Select_2_ID) and LEFT JOIN'd them together using the Select 1's ID).
Rather long-winded but it works - I suspect it isn't very efficient though, Thankfully it only returns 24k rows.

Related

How to add sum of a column as a new row after a group in SQL select query

I have a select query which returns a couple of rows grouped by ParentId. How can I add a new row with sum of a column after each parentId group?
For now I have kept the data in a temp table and the result is as below.
And I want to add a new row at the end of each ParentId group as below with the sum of column LoanAmount.
Any help will be appreciated. Many thanks.
You can use a common table expression to achieve this. Here I've created a cte with rank column for getting it sorted in order.
;WITH cte AS
(SELECT ParentId,
sum(LoanAmount) LoanAmount,
max(rank) + 1 AS rank
FROM test
GROUP BY ParentId)
SELECT *
FROM test
UNION ALL
SELECT *
FROM cte
ORDER BY ParentId, rank
rextester
See this link here enter link description here
I think you want:
SELECT ParentID, SUM(VALUE1), SUM(VALUE2)
FROM tableName
GROUP BY ID
You cant do it after each group or at the bottom like in excel, but you create a 'new table' in your query effectively.
Yeah having seen your updated comment, you main issue is youre thinking of it like excel, SQL is not a spreadsheet tool - its a relational database. Id suggest going through a SQL intro - youll pick up the concepts quite fast.
The query I gave you could be created as a stored procedure.
If you feel I've answered your question, id appreciate an upvote :)
You can make sum of group by subquery then combine them in union
; with cte as
( select 9999 as Slno, Level, ParentId, Ent_id, relation, sum(colname) as colname from table group by Level, ParentId, Ent_id, relation)
, ct as ( select row_number() over (partition by ParentId order by level) as Slno, Level, ParentId, Ent_id, Name, --- rest of your column names
colname from table
union all
select Slno, Level, ParentId, Ent_id, '' as Name, ---rest of '' for each column with column name as alias
colname from cte )
select Slno, Level, ParentId, Ent_Id, Name, ---- your columns of table
colname from ct order by Slno
This is just rough idea. Feel free to ask for any confusion.
Post your exact schema for accurate details.

order by on set 1 union set 2 sql

I have this situation:
select name,
subject
from Table_1
where date > getdate()-1
group by name, subject
order by id desc
union
select name,
subject
from table_2
where name not like 'abc%'
Table_1 and table_2 has similar structure.
I need to order by in SET1 UNION SET 2
This is not allowed in sql server. says "ORDER BY items must appear in the select list". I dont understand why the problem is. I am selecting equal number of columns on both queries. only that I want the result set together.
(on SQL Server 2017)
Anybody help!!
Thanks in advance.
Elaborating on my comment
select name,
subject
from Table_1
where date > getdate()-1
--group by name, subject --this isn't needed
union
select name,
subject
from table_2
where name not like 'abc%'
order by <yourCol> desc --notice change here
And for a conditional order by, there are a few posts on that.
Also, you don't need the group by since union removes duplicates.
But, the error is clear that the column you want to order by must be contained in the select list...
If you want to keep the first set ordered before the second set, just use a static column....
select name,
subject,
1 as Sort
from Table_1
where date > getdate()-1
--group by name, subject --this isn't needed
union
select name,
subject,
2 as Sort
from table_2
where name not like 'abc%'
order by Sort asc--notice change here

Choose 2 Random Values from 2 Separate Columns SQL

I am having to prepare test data to send to a 3rd party however I don't wish to send the customers real name nor do I wish to send their real date of birth.
I could solve the D.O.B issue by just randomly increasing the DOB by several years. However the name is different, is there anyway I can have a list of say 10 customer names and just choose a different Firstname and Surname each time.
I wish to mix and match the names however so it essentially randomly picks 1 firstname and then randomly picks a lastname and puts them together on the same line.
SELECT TOP 1 opde.first_name
FROM Table AS opde
ORDER BY NEWID()
This will return a random first name each time, but if I put the surname column in it will also return the matching surname, I don't want that I want a random surname from the list.
I tried doing this via a UNION but you can't do an ORDER BY NEWID() in the UNION.
Cheers.
I think this one might help...
WITH fn AS
(
SELECT TOP 1 opde.first_name
FROM Table AS opde
ORDER BY NEWID()
),
sn AS
(
SELECT TOP 1 opde.surname
FROM Table AS opde
ORDER BY NEWID()
)
SELECT first_name, surname
FROM fn
CROSS APPLY sn;
In the fn subquery you select a random first name. In the sn you do the same but with an surname.
With the cross apply you combine those two results
You may use a union of subqueries, each of which uses order by with NEWID:
SELECT first_name
FROM
(SELECT TOP 1 opde.first_name FROM Table AS opde ORDER BY NEWID()) t1
UNION ALL
SELECT first_name
FROM
(SELECT TOP 1 opde.first_name FROM Table AS opde ORDER BY NEWID()) t2;
Demo

T-SQL, using Union to dedupe , but retain an additional column

I am using T-SQL to return records from the database (there are multiple criteria, but the list of unique ID's must be distinct), in short, the T-SQL looks like this:
SELECT
t1.ID,
[query1mark] = 1
WHERE criteria1 = 1
UNION
SELECT
t1.ID,
[query2mark] = 1
WHERE criteria2 = 1
I would like to be able to use Union to de-dupe on the ID field (the data has to be unique on the ID field), whilst retaining the derived column "query1mark" or "query2mark" to highlight which query it additionally came from. In my real world case, there are 5 queries that need to be de-duped against each other, so I need an efficient solution is possible.
EDIT: Additionally, the results from the first query need to be prioritised over those from the second query, and the results from the second query need to be prioritised over those from the third query, as I understand, this feature is inherent when using Union, as it will only add records from below the Union statement.
Is Union the best solution for this, and if not, what can I use?
Thanks
What about this:
DECLARE #DataSource TABLE
(
[ID] INT
,[criteria] INT
);
INSERT INTO #DataSource ([ID], [criteria])
VALUES (1, 1)
,(1, 2)
,(2, 1)
,(3, 1)
,(3, 2)
,(4, 2);
WITH DataSource ([ID], [query_mark], [RowID]) AS
(
SELECT *
,ROW_NUMBER() OVER (PARTITION BY [ID] ORDER BY [criteria] ASC)
FROM #DataSource
)
SELECT [id], [query_mark]
FROM DataSource
WHERE [RowID] = 1;
The idea is to create sequence of all duplicated elements for particular group. The duplicates are order by the criteria field, but yo can change the logic if you need - for example to show the biggest criteria. The group is defined using the PARTITION BY [ID] statement, which means, order items for each [ID] group. Then, in the select, we only need to show one record per each group [RowID] = 1
you can use top 1 with ties
SELECT top 1 with ties * FROM yourtable
ORDER BY ROW_NUMBER() OVER (PARTITION BY [ID] ORDER BY [criteria])

ORDER BY select statement using UNION & DISTINCT

I'm using the following query to populate a dropdown list of values.
select 'Select a City' as City, 'All' as Value
UNION ALL
select distinct City, City as Value from BND_Listing
I'd like to sort A-Z the results. I've tried the following:
select 'Select a City' as City, 'All' as Value
UNION ALL
select distinct City, City as Value from BND_Listing
ORDER BY City ASC
But am getting an error:
Incorrect syntax near the keyword 'Union'.
Additionally this query is pulling "Blank or NULL" values and displaying a blank space at the top of the drop-down. I'd like to hide that if possible. Not display any null value?
You want to add a row to your result, which is always on top and carries a NULL as ID?
Try this:
SELECT *
FROM
(
SELECT NULL AS col1,'select an object' AS col2,0 AS SortInx
UNION ALL
SELECT TOP 10 object_id,name,ROW_NUMBER() OVER(ORDER BY name)
FROM sys.objects
) AS Sortable
ORDER BY SortInx
Short explanation: ROW_NUMBER() start with 1, so the first row gets 0 as sort index. The numbers from 1 to x represent the sorted name's order.
The outer SELECT will sort the result-set again making sure, that 0 is in front and 1 to x following...
I agree with most of the comments here where the best approach is to actually have the "Select a Value" row added in the application itself. It's probably best to have the database only delivering "actual" data to your application and handle things like that in the code.
I'm also not sure what this project is for, but if you have access, I would strongly recommend creating views and/or stored procedures at the database level to abstract any database schema and logic changes from your application.
Just out of curiosity, why are you selecting the same field twice with different aliases? I'm assuming you're setting the display value and the actual value in a simple HTML dropdown, but in this case, the values are the same, so you could only have one field in your result set and reference that value twice in the application. Doing this would solve the problem of your original question, as well as simplify your query (although a query this simple is going to have negligible cost anyway) to look like this:
SELECT DISTINCT City
FROM BND_Listing (NOLOCK)
WHERE City IS NOT NULL
ORDER BY 1 ASC
Depending on the data, DB config, etc, you may need to account for empty strings and/or leading/trailing spaces with something like this:
SELECT DISTINCT LTRIM(RTRIM(City)) AS City
FROM BND_Listing (NOLOCK)
WHERE LTRIM(RTRIM(City)) <> ''
AND City IS NOT NULL
ORDER BY 1
Sorry...I know that may have been a little overkill, but you said you were new to SQL, so I thought I'd just share that in case your NULL results were actually empty strings.
Thank you everyone for the responses it gave me a lot of insight on where to look for my problem. The original query with the addition of the below achieved the proper result.
working query:
select 'Select a City' as City, 'All' as Value
UNION ALL
select distinct City, City as Value from BND_Listing
where isnull(City,'') <> ''
Order by City ASC
with 'Select a City' always at the top of the dropdown. Credit to #scsimon on my other post for this.
with cte as(
select 'Select a City' as City, 'All' as Value
UNION ALL
select distinct City, City as Value from BND_Listing
where isnull(City,'') <> '')
select * from cte Order by case when City = 'Select a City' then 1 else 2 end, City ASC

Resources