How do I add where condition? - sql

I want to add a condition according to the returned result

You can't reuse an alias defined in the SELECT clause in the FROM clause of the scope. You need to either repeat the expression, or use a subquery or CTE.
select dayofweek_iso(timestamp(mycol)) as mynewcol
from mytable
where dayofweek_iso(timestamp(mycol)) = 1
Or:
select *
from (
select dayofweek_iso(timestamp(mycol)) as mynewcol
from mytable
) t
where mynewcol = 1

Use your existing query as a subquery:
select * from (
<add your existing query in the screenshot here>
) t
where <add your conditions here>

i think you should include your code in the post itself. A picture like this is quite unhandy.
W3: SQL WHERE
as you can see here, just add your WHERE statement at the end:
SELECT * FROM XXX WHERE CONDITION

Out of interest, since Db2 11.5, you can reference a column alias in a WHERE clause if using NPS (i.e. Netezza compatibility) mode.
CREATE TABLE MYTABLE(MYCOL DATE)
SET SQL_COMPAT='NPS'
SELECT DAYOFWEEK_ISO(TIMESTAMP(MYCOL)) AS MYNEWCOL
FROM MYTABLE
WHERE MYNEWCOL = 1
Still, this is best reserved for users migrating from Netezza as NPS mode changes some other things too.

Related

How to do a Select in another Select with Postgresql

I must do this query in another Select in Postgresql :
SELECT COUNT(tn.autoship_box_transaction_id)
FROM memberships.autoship_box_transaction tn
WHERE tn.autoship_box_id = b.autoship_box_id
Do I must use the clause WITH ?
As long as the query produces a single data element, you can use it in place of an attribute:
SELECT (
SELECT COUNT(tn.autoship_box_transaction_id)
FROM memberships.autoship_box_transaction tn
WHERE tn.autoship_box_id = b.autoship_box_id
) AS cnt
, other_column
FROM wherever
;
Have a look at this SQL fiddle demonstrating the use case.
This method often comes with a performance penalty if the db engine actually iterates over the result set and performs the query on each record encountered.
The db engine's optimizer may be smart enough to avoid the extra cost (and it should in the fiddle's toy example), but you have to look at the explain plan to be sure.
Note that its mostly an issue with 'correlated subqueries', ie. queries embedded as shown which depend on the embedding. Your example example appears to be of this kind as you use a table alias b which isn't defined anywhere.
There might be the option of moving the subselect to the from clause (beware: This statement is for explanatory purposes only; you must adapt it to your use case, I am just wild guessing here):
SELECT stats.cnt
, b.other_column
FROM b_table b
JOIN (
SELECT COUNT(tn.autoship_box_transaction_id) cnt
, tn.autoship_box_id
FROM memberships.autoship_box_transaction tn
GROUP BY tn.autoship_box_id
) stats
ON (stats.autoship_box_id = b.autoship_box_id)
;
There are two options. You can either use the with clause, like so:
WITH some_count AS (
SELECT COUNT(tn.autoship_box_transaction_id)
FROM memberships.autoship_box_transaction tn
WHERE tn.autoship_box_id = b.autoship_box_id
)
SELECT * FROM some_count;
Or the second option is to use a sub-query, like so:
SELECT
*
FROM
(
SELECT COUNT(tn.autoship_box_transaction_id)
FROM memberships.autoship_box_transaction tn
WHERE tn.autoship_box_id = b.autoship_box_id
);

'In' clause in SQL server with multiple columns

I have a component that retrieves data from database based on the keys provided.
However I want my java application to get all the data for all keys in a single database hit to fasten up things.
I can use 'in' clause when I have only one key.
While working on more than one key I can use below query in oracle
SELECT * FROM <table_name>
where (value_type,CODE1) IN (('I','COMM'),('I','CORE'));
which is similar to writing
SELECT * FROM <table_name>
where value_type = 1 and CODE1 = 'COMM'
and
SELECT * FROM <table_name>
where value_type = 1 and CODE1 = 'CORE'
together
However, this concept of using 'in' clause as above is giving below error in 'SQL server'
ERROR:An expression of non-boolean type specified in a context where a condition is expected, near ','.
Please let know if their is any way to achieve the same in SQL server.
This syntax doesn't exist in SQL Server. Use a combination of And and Or.
SELECT *
FROM <table_name>
WHERE
(value_type = 1 and CODE1 = 'COMM')
OR (value_type = 1 and CODE1 = 'CORE')
(In this case, you could make it shorter, because value_type is compared to the same value in both combinations. I just wanted to show the pattern that works like IN in oracle with multiple fields.)
When using IN with a subquery, you need to rephrase it like this:
Oracle:
SELECT *
FROM foo
WHERE
(value_type, CODE1) IN (
SELECT type, code
FROM bar
WHERE <some conditions>)
SQL Server:
SELECT *
FROM foo
WHERE
EXISTS (
SELECT *
FROM bar
WHERE <some conditions>
AND foo.type_code = bar.type
AND foo.CODE1 = bar.code)
There are other ways to do it, depending on the case, like inner joins and the like.
If you have under 1000 tuples you want to check against and you're using SQL Server 2008+, you can use a table values constructor, and perform a join against it. You can only specify up to 1000 rows in a table values constructor, hence the 1000 tuple limitation. Here's how it would look in your situation:
SELECT <table_name>.* FROM <table_name>
JOIN ( VALUES
('I', 'COMM'),
('I', 'CORE')
) AS MyTable(a, b) ON a = value_type AND b = CODE1;
This is only a good idea if your list of values is going to be unique, otherwise you'll get duplicate values. I'm not sure how the performance of this compares to using many ANDs and ORs, but the SQL query is at least much cleaner to look at, in my opinion.
You can also write this to use EXIST instead of JOIN. That may have different performance characteristics and it will avoid the problem of producing duplicate results if your values aren't unique. It may be worth trying both EXIST and JOIN on your use case to see what's a better fit. Here's how EXIST would look,
SELECT * FROM <table_name>
WHERE EXISTS (
SELECT 1
FROM (
VALUES
('I', 'COMM'),
('I', 'CORE')
) AS MyTable(a, b)
WHERE a = value_type AND b = CODE1
);
In conclusion, I think the best choice is to create a temporary table and query against that. But sometimes that's not possible, e.g. your user lacks the permission to create temporary tables, and then using a table values constructor may be your best choice. Use EXIST or JOIN, depending on which gives you better performance on your database.
Normally you can not do it, but can use the following technique.
SELECT * FROM <table_name>
where (value_type+'/'+CODE1) IN (('I'+'/'+'COMM'),('I'+'/'+'CORE'));
A better solution is to avoid hardcoding your values and put then in a temporary or persistent table:
CREATE TABLE #t (ValueType VARCHAR(16), Code VARCHAR(16))
INSERT INTO #t VALUES ('I','COMM'),('I','CORE')
SELECT DT. *
FROM <table_name> DT
JOIN #t T ON T.ValueType = DT.ValueType AND T.Code = DT.Code
Thus, you avoid storing data in your code (persistent table version) and allow to easily modify the filters (without changing the code).
I think you can try this, combine and and or at the same time.
SELECT
*
FROM
<table_name>
WHERE
value_type = 1
AND (CODE1 = 'COMM' OR CODE1 = 'CORE')
What you can do is 'join' the columns as a string, and pass your values also combined as strings.
where (cast(column1 as text) ||','|| cast(column2 as text)) in (?1)
The other way is to do multiple ands and ors.
I had a similar problem in MS SQL, but a little different. Maybe it will help somebody in futere, in my case i found this solution (not full code, just example):
SELECT Table1.Campaign
,Table1.Coupon
FROM [CRM].[dbo].[Coupons] AS Table1
INNER JOIN [CRM].[dbo].[Coupons] AS Table2 ON Table1.Campaign = Table2.Campaign AND Table1.Coupon = Table2.Coupon
WHERE Table1.Coupon IN ('0000000001', '0000000002') AND Table2.Campaign IN ('XXX000000001', 'XYX000000001')
Of cource on Coupon and Campaign in table i have index for fast search.
Compute it in MS Sql
SELECT * FROM <table_name>
where value_type + '|' + CODE1 IN ('I|COMM', 'I|CORE');

Table name after parenthesis notation

I was going through some old-ish SQL code someone else had written that I couldn't quite understand. I have simplified its structure here, but if anyone can walk me through what exactly is going on, that would be appreciated! You may ignore the specific column operations as they were just examples.
SELECT table.*,
column1 - column2
AS 'col1 - col2',
...
columnn
AS 'coln'
FROM
(SELECT
...
) table
What I don't understand is the final line. I am assuming it is the definition of "table" in the FROM (SELECT ...) part, and the ) table part indicates the name of the defined table.
Thanks in advance!
An inner select needs an alias name
select alias_name.* from
(
select * from some_table ...
) alias_name
The 'table' in that final line is an alias for the subquery.
In T-SQL it is AFAIK mandatory to specify an alias for a subquery if you're selecting from a subquery.
You can name the alias whathever you want. It is perfectly ok to use it like this
select * from
( select * from ... ) as X
(The as keyword is not mandatory, but I always specify the alias-name using 'as').

Querying the Result set of a Previous Query

I have a query for example Query1 = Select Name from table where some Criteria.
Now this query returns a result set of course, what I want is to query the result set of this query, for example I only want the unique Names from the above query select Distinct(Name) from Query1. I should mention that I know I can just use distinct in Query1 but this is just an example my real scenario is somewhat different, what I want to know is whether it's possible to query the result set of a previous query.
I am using SQL Server 2012.
There are several ways to solve this:
1: create a view from the first query and run the second query on the view.
2: nest both queries, like this:
SELECT DISTINCT [Name]
FROM (
SELECT [Name]
FROM table
WHERE some Criteria
) As InnerQuery
3: use a temporary table to store the resultset of the first query as suggested by wewesthemenace in the comments.
4: use CTE as suggested the thebreiflabb in the other answer to this post.
Personally, I would probably go with the first or second option, depending if you need to use the first query as stand alone as well.
You can use the WITH clause
WITH SomeClients AS (
SELECT
c.ID
FROM Clients c
WHERE c.Name LIKE '%hello%'
)
SELECT DISTINCT
sc.ID
FROM SomeClients sc
You need WITH clause. The Syntax Is-
WITH someName AS(
//Your Db Query
)
SELECT * FROM someName // OR Whatever you want
you can create a table to store the results temporarily and use that table in a new query
DECLARE #resultset table (
ID int identity(1,1) not null
, name nvarchar(100)
)
Select top 50 application_Name
into resultset
from Applications_ASIS

where clauses in max statement

how it is possible to add where to query , to do converting or replacing or max value!
max(convert(int,replace(( QueueNum ),'-',''))) from [Queue]
i want to return max of records that have something special , in where clauses for QueueNum .
Edited :
Data :
1981-1-1232
1981-1-1235
1981-1-1234
1981-2-1
1981-2-2
1981-2-13
how it is possible to return max value of just record started with 1981-2
I guess it is MSSql database in this case try to use the following statement without any conversion:
SQLfiddle demo
select TOP 1
QueueNum
from Queue where QueueNum like '1981-2-%'
order by LEN(QueueNum) desc, QueueNum desc
Not sure if I am giving a good answer, but you can write your query as
Select max(MyValue) from (Select Convert(int, replace((QueueNum),'-','')) as MyValue from [Queue]) MyTable
What it does is that it create a Temporary table in memory which is of one column MyValue and of type Int, this then find Max from that table. I notice that sometime "MyTable" [table alias] is important in such query to perform especially on SQl Server.
Put your condition in having clause
Is this what you want?
SELECT MAX(CONVERT(INT, REPLACE((QueueNum),'-','')))
FROM Queue
WHERE QueueNum LIKE '1981-2%'
SQLFiddle.