DB2 AS/400 iseries Use alias in where clause - sql

I'm trying to use the alias of a column in the where clause. for example:
SELECT col1 AS alias1, col2 + col3 as sums
FROM my_table
WHERE sums > 10
But then I get an error message saying:
Column sums not in specified tables.
Is there anyway I can do this?

If you really want to use alias in WHERE, not the column itself, you can do it with derived table :
SELECT a.*
FROM
(
SELECT lmITNO AS Item_Number, lmBANO AS Lot, lmSTAS AS Status,
lmRORN AS Order_Number
FROM MVXJDTA.MILOMA
) a
WHERE a.Status = 'CCC'
....

The where-clause is processed before the select-clause in a statement:
The WHERE clause specifies an intermediate result table that consists of those rows of R for which the search-condition is true. R is the result of the FROM clause of the statement.
Re-write the where-clause to reference the actual column name:
...
WHERE A.lmSTAS = 'CCC'
...
A common-table-expression can be used to pre-process the select-clause. For example:
WITH A AS (SELECT
lmITNO AS Item_Number,
lmBANO AS Lot,
lmSTAS AS Status,
lmRORN AS Order_Number
FROM MVXJDTA.MILOMA)
SELECT A.* FROM A WHERE A.Status = 'CCC'
FETCH FIRST 1000 ROWS ONLY
The columns in a CTE can also be renamed by listing them after the table-identifier. For example:
WITH A (Item_Number, Lot, Status, Order_Number)
AS (SELECT
lmITNO,
lmBANO,
lmSTAS,
lmRORN
FROM MVXJDTA.MILOMA)
SELECT A.* FROM A WHERE A.Status = 'CCC'
FETCH FIRST 1000 ROWS ONLY

Related

SELECT specific ONLY if exists, otherwise return ALL

How can I write WHERE cluase so it returns rows that meet the criteria, if there are no such records it should return all records from a table?
Using UNION ALL:
select t.* from table t where condition
union all
select t.* from table t cross join (select count(*) cnt from table where condition) c
where c.cnt=0
Or (much more efficiently):
select col1, col2, ... colN
from
(
select t.*, sum(case when condition then 1 else 0 end) over() cnt from table
) s
where condition or s.cnt=0
Replace condition with your WHERE condition
One method you could consider in t-sql is to use ##rowcount to determine if you need to return all rows.
The benefit of doing so is you get two separate execution plans, one only optimised for your first exists criteria and would be beneficial if the majority of results are where the exists condition is met.
select <columns>
from <table>
where <condition>
if ##rowcount=0
begin
select <columns>
from <table>
end
One way would be:
SELECT *
FROM Person
WHERE
Name = 'John'
OR NOT EXISTS(SELECT null FROM Person WHERE Name = 'John')
I don't like it, for all those good reasons mentioned in the comments. If I was handed this requirement as part of a system I was creating I'd probably examine the need for the requirement; selecting all rows from a table is seldom useful if it's the sort of table that you query with a criteria: "Dear user, we couldn't find your person named John so here are the other 4.27 billion users in the system, pagination size 100"
that satisfies me enough:
WHERE (
ISNULL(#variable, '') = ''
OR #variable = [Column]
)
Not exactly what I described above but it returns all the records if condition is not met. However in that case condition would be assigning a value to variable.
1st method
Where ( ISNULL(#Param,'')='' OR ColumnName = #Param)
2nd way
WHERE ( ColumnName =CASE WHEN #Param IS NULL THEN ColumnName
ELSE #Param
END)
3rd way
WHERE (#Param ='' OR #Param =ColumnName)
I would recommend a CTE with not exists:
with cte as (
select t.*
from t
where . . .
)
select *
from cte
union all
select *
from t
where not exists (select 1 from cte);

How to get also the not existing values

I've got a query like this
select column, count(*)
from mytable
where column in ('XXX','YYY','ZZZ',....)
group by column;
But I want also to get a row for values the aren't in the table.
Let's suppose that 'ZZZ' doesn't exist in mytable, I'd like to get:
COLUMN COUNT(*)
XXX 3
YYY 2
ZZZ 0 (or NULL)
Oracle version 10g
Thanks in advance
Mark
In general, you would need to have a second table which contains all the possible column values whose counts you want to appear in the output. For demo purposes only, we can use a CTE for that:
WITH vals AS (
SELECT 'XXX' AS val UNION ALL
SELECT 'YYY' UNION ALL
SELECT 'ZZZ'
)
SELECT t1.val, COUNT(t2.col) AS cnt
FROM vals t1
LEFT JOIN mytable t2
ON t2.col = t1.val
GROUP BY
t1.val;

Union of multiple queries using the count function

I'm working on learning more about how the UNION function works in SQL Server.
I've got a query that is directed at a single table:
SELECT Category, COUNT(*) AS Number
FROM Table1
GROUP BY Category;
This returns the number of entries for each distinct line in the Category column.
I have multiple tables that are organized by this Category column and I'd like to be able to have the results for every table returned by one query.
It seems like UNION will accomplish what I want it to do but the way I've tried implementing the query doesn't work with COUNT(*).
SELECT *
FROM (SELECT Table1.Category
Table1.COUNT(*) AS Number
FROM dbo.Table1
UNION
SELECT Table2.Category
Table2.COUNT(*) AS Number
FROM dbo.Table2) AS a
GROUP BY a.Category
I'm sure there's an obvious reason why this doesn't work but can anyone point out what that is and how I could accomplish what I'm trying to do?
You cannot write a common Group by clause for two different select's. You need to use Group by clause for each select
SELECT TABLE1.Category, --missing comma here
COUNT(*) as Number -- Remove TABLE1. alias name
FROM dbo.TABLE1
GROUP BY Category
UNION ALL --UNION
SELECT TABLE2.Category, --missing comma here
COUNT(*) as Number -- Remove TABLE1. alias name
FROM dbo.TABLE2
GROUP BY Category
If you really want to remove duplicates in result then change UNION ALL to UNION
COUNT as any associated aggregation function has to have GROUP BY specified. You have to use group by for each sub query separately:
SELECT * FROM (
SELECT TABLE1.Category,
COUNT(*) as Number
FROM dbo.TABLE1
GROUP BY TABLE1.Category
UNION ALL
SELECT TABLE2.Category,
COUNT(*) as Number
FROM dbo.TABLE2
GROUP BY TABLE2.Category
) as a
It is better to use UNION ALL vs UNION - UNION eliminates duplicates from result sets, since - let say - you want to merge both results as they are it is safer to use UNION ALL

Using a value from one query in second query sql

SELECT AS, COUNT(*)
FROM Table1
HAVING COUNT(AS)>1
group BY AS;
This produces the result
AS COUNT
5 2
I then want to use the AS value in another query and only output the end result. Is this possible.i was thinking something like.
SELECT *
FROM
TABLE 2
Where AS =(
SELECT AS, COUNT(*)
FROM Table1
HAVING COUNT(AS)>1
group BY AS;
);
This is called a subquery. To be safe, you would use in instead of = (and as is a bad name for a column, because it is a SQL key word):
SELECT *
FROM TABLE2
WHERE col IN (SELECT col
FROM Table1
GROUP BY col
HAVING COUNT(col) > 1
);
Your first query is also incorrect, because the having clause goes after the group by.
You could use a subquery with the in operator:
SELECT *
FROM table2
WHERE AS IN (SELECT AS
FROM table1
GROUP BY AS
HAVING COUNT(*) > 1)

order by only one dataset of a union in a tsql union of datasets

I have the following problem.
Let TableA(Id int, Name nvarchar(200)) and TableB(Id int, Name nvarchar(200)).
If we run the following query:
SELECT *
FROM
(SELECT *
FROM TableA)
UNION
(SELECT *
FROM TableB)
we get the union of the two datasets.
My Problem is that I want the results of the second dataset to be the ordered by the Name column.
The reason why I need this, is the fact that TableA is a temporary table in my query, that always will hold one record, and this record I want to be the first in the resulting dataset from the union of the two datasets. Also, I want the multiple records of the TableB to be ordered by the Name column.
Unfortunately, when I try to execute the following query
SELECT *
FROM
(SELECT *
FROM TableA)
UNION
(SELECT *
FROM TableB
ORDER BY Name)
I get an ambiguous error message, that informs me that I have an incorrect syntax near the keyword order.
Thanks in advance for any help.
try this:
select id
, name
from
(select 1 as ordercol
, a.id
, a.name
from tableA
union
select 2 as ordercol
, b.id
, b.name
from tableB) i
order by ordercol, name
the error message resulted in you trying to union two subselects. you can put union between two selects that will then be put into a subselect. there is always a select after a union (or union all). i would also suggest you use a union all, that saves time because sql-server will otherwise try and remove records that are in both selects (which in this case is impossible due to the ordercol-column)
i have included a second order-by column that will order the first select before the second. if you order by that first and then by name, you should get the desired result.