I've got a situation where I'm using a named column as such:
SELECT title, SUBSTR(title, 1, 2) as nameprefix FROM employees
Now the issue is that I'd like to add another named column and somehow refer to nameprefix in it. Is this possible? Essentially I would like to do this:
SELECT title, SUBSTR(title, 1, 2) as nameprefix,
(CASE WHEN nameprefix = 'Dr' THEN 'FOUND' ELSE 'NOPE' END) as flag
FROM employees
It complains with an error: Error: no such column: nameprefix. The actual use-case involves complex sub-queries and I'd like to be able to re-use their results rather than duplicating these sub-queries in each column that requires the result.
this is possible:
select title, nameprefix from
(
select title, SUBSTR(title, 1, 2) as nameprefix FROM employees
)
where nameprefix = 'Dr'
Sounds like you wish to view the table as if the first two characters of the title field are considered a separate, named column. So, I'd use CREATE VIEW to build exactly that view and then query against it, rather than against the underlying table.
So, in your case, issue something like
CREATE VIEW EmployeesWithCols (Name, Title, NamePrefix) AS
SELECT Name, Title, SUBSTR(title, 1, 2) FROM Employee
Now, simply replace the table employee in your original query with employeeswithcols and you will magically have a new NamePrefix column available. Of course, you'll probably need some additional columns in the view as well.
As a side note, I generally name views that are used only to add virtual computed columns to a single table with the table name and prefix "Ex" (as per many internal Windows functions) but in this case and many others that naming convention is ripe for embarrassment if you are not rigorous about the letter case in which you write the view name.
You can use alias in select you must repeat the code
SELECT title, SUBSTR(title, 1, 2) as nameprefix,
CASE WHEN SUBSTR(title, 1, 2)= 'Dr' THEN 'FOUND' ELSE 'NOPE' END as flag
FROM employees
of use a subselect eg:in join
SELECT title, t.nameprefix ,
CASE WHEN nameprefix = 'Dr' THEN 'FOUND' ELSE 'NOPE' END as flag
FROM employees
JOIN (select id, SUBSTR(title, 1, 2) as nameprefix
FROM employees ) t on t.id = employees.id
Related
I'd like to conditionally include the values from particular columns in a SQL query. To illustrate the question let me use the fictional example of returning selective data about users.
If we were to return all data we'd use a query of the form:
SELECT
name, email, gender
FROM
users
Assume all users have entered their gender. However some have set the value of gender_public to be false and I would like to reflect this in the data the query returns.
The type of thing I'd like to do is:
SELECT
name, email, if(gender_public, gender, 'N/A')
FROM
users
Is this possible? I'm working with Postgres
Using CASE
This is the obvious way to go, as suggested by #a_horse_with_no_name.
Assuming gender_public is of type BOOLEAN.
SELECT name, email, CASE WHEN gender_public THEN gender ELSE 'N/A' END AS gender
FROM users;
Using lateral join
This way of doing is especially useful if you need to use the value in more than one place and want to remain consistent.
SELECT name, email, T.gender
FROM users
CROSS JOIN LATERAL (
SELECT gender WHERE show_gender
UNION
SELECT 'N/A' WHERE NOT(show_gender)
) T(gender)
I have two objects named as 'Opportunity' and 'Account.
I need to select ID, OpportunityName,CreatedDate from Opportunity table and AccountName, AccountCat from Account table where Account.OpportunityID = Opportunity.ID and AccountCat = 'DC'.
I refer this tutorial and executed in workbench, but didn't work.
Following is the query I used.
SELECT AccountName, AccountCat (SELECT Id, OpportunityName,CreatedDate FROM Opportunity) FROM Account WHERE OpportunityID
IN (SELECT Id FROM Opportunity) AND AccountCat = 'DC'
Run your query on the Opportunity object and then use reference fields to select fields from the parent object.
SELECT Id
, Name
, CreatedDate
, Account.Name
FROM Opportunity
WHERE Account.Name = 'GenePoint'
AccountCat is not a standard field, so I assume it's a custom field, in which case you need to use the developer name, probably something like Account.Cat__c or Account.Category__c or something like that.
SOQL is superficially similar to SQL, but there are significant differences, one of them being how records are joined.
I need the second column of the table retrieved from a query to have a count of the number of rows, so row one would have a 1, row 2 would have a 2 and so on. I am not very proficient with sql so I am sorry if this is a simple task.
A basic example of what I am doing would be is:
SELECT [Name], [I_NEED_ROW_COUNT_HERE],[Age],[Gender]
FROM [customer]
The row count must be the second column and will act as an ID for each row. It must be the second row as the text file it is generating will be sent to the state and they require a specific format.
Thanks for any help.
With your edit, I see that you want a row ID (normally called row number rather than "count") which is best gathered from a unique ID in the database (person_id or some other unique field). If that isn't possible, you can make one for this report with ROW_NUMBER() OVER (ORDER BY EMPLOYEE_ID DESC) AS ID, in your select statement.
select Name, ROW_NUMBER() OVER (ORDER BY Name DESC) AS ID,
Age, Gender
from customer
This function adds a field to the output called ID (see my tips at the bottom to describe aliases). Since this isn't in the database, it needs a method to determine how it will increment. After the over keyword it orders by Name in descending order.
Information on Counting follows (won't be unique by row):
If each customer has multiple entries but the selected fields are the same for that user and you are counting that user's records (summed in one result record for the user) then you would write:
select Name, count(*), Age, Gender
from customer
group by name, age, gender
This will count (see MSDN) all the user's records as grouped by the name, age and gender (if they match, it's a single record).
However, if you are counting all records so that your whole report has the grand total on every line, then you want:
select Name, (select count(*) from customer) as "count", Age, Gender
from customer
TIP: If you're using something like SSMS to write a query, dragging in columns will put brackets around the columns. This is only necessary if you have spaces in column names, but a DBA will tend to avoid that like the plague. Also, if you need a column header to be something specific, you can use the as keyword like in my first example.
W3Schools has a good tutorial on count()
The COUNT(column_name) function returns
the number of values (NULL values will not be counted) of the
specified column:
SELECT COUNT(column_name) FROM table_name;
The COUNT(*) function returns the number of records in a table:
SELECT COUNT(*) FROM table_name;
The COUNT(DISTINCT column_name) function returns the number of
distinct values of the specified column:
SELECT COUNT(DISTINCT column_name) FROM table_name;
COUNT(DISTINCT) works with ORACLE and Microsoft SQL Server, but
not with Microsoft Access.
It's odd to repeat the same number in every row but it sounds like this is what you're asking for. And note that this might not work in your flavor of SQL. MS Access?
SELECT [Name], (select count(*) from [customer]), [Age], [Gender]
FROM [customer]
So, I have a table with the columns staff, associate and Matter type (which is always either set to 'Lit' or 'PSD'.)
When type field = 'Lit' I need to include the Staff field as the staff field in the select statement. When the type field is set to 'PSD' I need to include the associate field as the staff field in the select statement.
I know I can do this as two separate queries, but I cannot figure out how to combine the two into a single query - there's an easy answer, but after not being able to figure it out for a while, I'm just not coming up with the answer.
Ideas?
SELECT
CASE WHEN
[MatterType] = 'Lit'
THEN
[Staff]
ELSE
[Associate]
END AS [NewStaff]
FROM
MyTable;
This uses an inline case condition in the SELECT list.
To combine the results of two queries with same number of columns, you can use UNION ALL or UNION. Preferably union all because of less overhead.
SELECT staff AS staff ,
mattertype
FROM my_table
WHERE mattertype = 'Lit'
UNION ALL
SELECT associate AS staff ,
mattertype
FROM my_table
WHERE mattertype = 'PSD'
In your case, I would say using CASE is better:
SELECT CASE WHEN mattertype = 'Lit' THEN staff
ELSE associate
END AS staff
,mattertype
FROM my_table
If I understand your question right you want either staff or associate as a column called staff depending on the value of matter. If this is the cas you can use a conditional case ... when statement to select the appropriate columns. Something like this:
select matter, case when matter = 'Lit' then staff else associate end as staff from table
As you state that matter has to be either Lit or PSD you only need to check if it is one of the values, otherwise it has to be the other (although you could make the check explicit for clarity).
The other answers have covered the common & practical, so here is a variation which is sometimes useful. If your staff column is null when [Matter type] = 'PSD' then this would work:
SELECT COALESCE(staff,associate) AS staff
FROM tablename
;
I want to display Alias name based on the value of some other column name in the query in SQL Server. For e.g.
SELECT P.Amount AS (CASE P.Type WHEN 'Individual' THEN 'Salary' ELSE 'Profit' END)
FROM Person P
I know the above is not right, but something like this will help.
I'm not sure if you can add dynamic aliases, but you should be able to do something like this (if you have only a few possible aliases):
SELECT
CASE P.Type WHEN 'Individual' THEN P.Amount ELSE NULL END AS Salary,
CASE P.Type WHEN 'Individual' THEN NULL ELSE P.Amount END AS Profit
FROM
Person p
The "Alias" name is the name of the entire column of the data you are returning. It is not possible for this to change on a "by row" basis.
The only way you can change a column name (alias) dynamically is using dynamic SQL to build up your query. However, this does not appear to be what you are wanting to do.
You'd need to return Amount as "Amount" and then return an extra column containing the "type" for that amount.
i.e.g
SELECT P.Amount, CASE P.Type WHEN 'Individual' THEN 'Salary' ELSE 'Profit' END AS AmountType
FROM Person P
No can do...
SQL returns a recorset which can only have one name / alias per each column.
Which name would it choose it example given if some records returned by the query were 'Individual' and some were some other type?
Of course, as suggested in several responses, you can modify the number of columns returned by the query and name each column as desired but dealing with such a results set that may then require additional logic, which would defeat the purpose since if one wanted extra logic, he/she may just select both the Amount and the Type and work off these values for attribute naming and such at the level of the application...
A column can have one and only one name. If your rowset contained only one row, then you could look at the row's Type column first and then change the column name appropriately for the select. If it contains multiple rows, it's simply not possible.
IF 1 = (SELECT COUNT(*) FROM Person P WHERE <where-criteria>) THEN
IF 'Individual' = (SELECT P.Type FROM Person P WHERE <where-criteria>) THEN
SELECT P.Amount AS Salary
FROM Person P
WHERE <where-criteria>
ELSE
SELECT P.Amount AS Profit
FROM Person P
WHERE <where-criteria>
END IF
ELSE
SELECT P.Amount AS SalaryOrProfit
FROM Person P
WHERE <where-criteria>
END IF
I think you might need to re-examine your design.