Distinct one column return selected columns and order by date desc using sybase - numbers

Hi Guys i have a problem on how im going to distinct single column and return selected column
Ac_no ord_status order_no
12334 PL 1
12334 ML 2
12334 CL 3
64543 PL 1
65778 JL 6
83887 CL 4
83887 KL 3
Ac_no ord_statu sorder_no
12334 CL 3
64543 PL 1
65778 JL 6
83887 CL 4
i want to see that result
here is my sample or code but unfortunately the code didnt work in sybase 1.2.0.637
SELECT Ac_no, ord_status, order_no
select *, ROW_NUMBER() OVER (PARTITION BY Ac_no order by ord_status)rm
from wo_order)x
where x = 1

It appears that you want to display, for each Ac_no group of records, the single record having the lowest ord_status. You were on the right track, but you need to restrict the subquery using the alias you defined for the row number:
SELECT Ac_no, ord_status, order_no
FROM
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY Ac_no ORDER BY ord_status) rn
FROM wo_order
) t
WHERE rn = 1;
Here is a version which should run on your version of Sybase, even without using ROW_NUMBER:
SELECT w1.Ac_no, w1.ord_status, w1.order_no
FROM wo_order w1
INNER JOIN
(
SELECT Ac_no, MIN(ord_status) AS min_ord_status
FROM wo_order
GROUP BY Ac_no
) w2
ON w1.Ac_no = w2.Ac_no AND
w1.ord_status = w2.min_ord_status;

Should work without a window function:
select t1.* from wo_order t1,
(select max(order_no) order_no, ac_no from wo_order group by ac_no) t2
where
t1.ac_no=t2.ac_no
and t1.order_no=t2.order_no

Related

TSQL -- display results of two queries on one row in SSMS

I am using TSQL, SSMS v.17.9.1 The underlying db is Microsoft SQL Server 2014 SP3
For display purposes, I want to concatenate the results of two queries:
SELECT TOP 1 colA as 'myCol1' FROM tableA
--
SELECT TOP 1 colB as 'myCol2' FROM tableB
and display the results from the queries in one row in SSMS.
(The TOP 1 directive would hopefully guarantee the same number of results from each query, which would assist displaying them together. If this could be generalized to TOP 10 per query that would help also)
This should work for any number of rows, it assumes you want to pair ordered by the values in the column displayed
With
TableA_CTE AS
(
SELECT TOP 1 colA as myCol1
,Row_Number() OVER (ORDER BY ColA DESC) AS RowOrder
FROM tableA
),
TableB_CTE AS
(
SELECT TOP 1 colB as myCol2
,Row_Number() OVER (ORDER BY ColB DESC) AS RowOrder
FROM tableB
)
SELECT A.myCol1, B.MyCol2
FROM TableA_CTE AS A
INNER JOIN TableB_CTE AS B
ON A.RowOrder = B.RowOrder
There are currently two issues with the accepted answer:
I) a missing comma before the line: "Table B As"
II) TSQL seems to find it recursive as written, so I re-wrote it in a non-recursive way:
This is a re-working of the accepted answer that actually works in T-SQL:
USE [Database_1];
With
CTE_A AS
(
SELECT TOP 1 [Col1] as myCol1
,Row_Number() OVER (ORDER BY [Col2] desc) AS RowOrder
FROM [TableA]
)
,
CTE_B AS
(
SELECT TOP 1 [Col2] as myCol2
,Row_Number() OVER (ORDER BY [Col2] desc) AS RowOrder
FROM [TableB]
)
SELECT A.myCol1, B.myCol2
FROM CTE_A AS A
INNER JOIN CTE_B AS B
ON ( A.RowOrder = B.RowOrder)

Eliminate duplicate values on an inner join (is it even possible given this scenario?)

I have a query that pulls information from two different tables at a different granular level. I was wondering if it is even possible to keep the value from repeating on the right (only return one row with 110811.67 rest zero) and preserve all values on the left.
select x.pt_year,
x.pt_month,
x.pt_amount,
y.fp_earnedprem
from
(
select sum(a.amount) as pt_amount
, va.ACCT_YEAR as pt_year, va.ACCT_MONTHINYEAR as pt_month, ptp.PTRANS_CODE as pt_code
from fact_policytransaction a
join VDIM_ACCOUNTINGDATE va
on a.ACCOUNTINGDATE_ID=va.ACCOUNTINGDATE_ID
join DIM_POLICYTRANSACTIONTYPE ptp
on a.POLICYTRANSACTIONTYPE_ID=ptp.POLICYTRANSACTIONTYPE_ID
group by va.ACCT_YEAR, va.ACCT_MONTHINYEAR, ptp.PTRANS_CODE
) as x
join
(
select sum(fp.EARNED_PREM_AMT) as fp_earnedprem
, dm.MON_YEAR as fp_year, dm.MON_MONTHINYEAR as fp_month
from fact_policycoverage fp
join dim_month dm on fp.MONTH_ID=dm.MONTH_ID
group by dm.MON_YEAR, dm.MON_MONTHINYEAR
) as y
on x.pt_year = y.fp_year
and x.pt_month = y.fp_month
where x.pt_year=2016 and x.pt_month=6
order by x.pt_year, x.pt_month
pt_year pt_month pt_amount fp_earnedprem
2016 6 4340.00 110811.67
2016 6 15569.00 110811.67
2016 6 30024.00 110811.67
pt_year pt_month pt_amount fp_earnedprem
2016 6 4340.00 110811.67
2016 6 15569.00 0
2016 6 30024.00 0
you can use ROW_NUMBER
;with cte as (
select x.pt_year,
x.pt_month,
x.pt_amount,
y.fp_earnedprem
from
(
select sum(a.amount) as pt_amount
, va.ACCT_YEAR as pt_year, va.ACCT_MONTHINYEAR as pt_month, ptp.PTRANS_CODE as pt_code
from fact_policytransaction a
join VDIM_ACCOUNTINGDATE va
on a.ACCOUNTINGDATE_ID=va.ACCOUNTINGDATE_ID
join DIM_POLICYTRANSACTIONTYPE ptp
on a.POLICYTRANSACTIONTYPE_ID=ptp.POLICYTRANSACTIONTYPE_ID
group by va.ACCT_YEAR, va.ACCT_MONTHINYEAR, ptp.PTRANS_CODE
) as x
join
(
select sum(fp.EARNED_PREM_AMT) as fp_earnedprem
, dm.MON_YEAR as fp_year, dm.MON_MONTHINYEAR as fp_month
from fact_policycoverage fp
join dim_month dm on fp.MONTH_ID=dm.MONTH_ID
group by dm.MON_YEAR, dm.MON_MONTHINYEAR
) as y
on x.pt_year = y.fp_year
and x.pt_month = y.fp_month
where x.pt_year=2016 and x.pt_month=6
)
, Rn as (
select *
, ROW_NUMBER() over (partition by pt_year, pt_month order by pt_year, pt_month) as RoNum
from cte
)
select pt_year, pt_month, pt_amount
, IIF(RoNum = 1, fp_enarnedprem, 0)
from Rn
order by pt_year, pt_month
the main part is your own query, I only added below section and a line on top and moved order by to the bottom.
)
, Rn as (
select *
, ROW_NUMBER() over (partition by pt_year, pt_month order by pt_year, pt_month) as RoNum
from cte
)
select pt_year, pt_month, pt_amount
, IIF(RoNum = 1, fp_enarnedprem, 0)
from Rn
order by pt_year, pt_month

JOIN tables inside a subquery in DB2

I'm having trouble with paginating with joined tables in DB2. I want to return rows 10-30 of a query that contains an INNER JOIN.
This works:
SELECT *
FROM (
SELECT row_number() OVER (ORDER BY U4SLSMN.SLNAME) AS ID,
U4SLSMN.SLNO, U4SLSMN.SLNAME, U4SLSMN.SLLC
FROM U4SLSMN) AS P
WHERE P.ID BETWEEN 10 AND 30
This does not work:
SELECT *
FROM (
SELECT row_number() OVER (ORDER BY U4SLSMN.SLNAME) AS ID,
U4SLSMN.SLNO, U4SLSMN.SLNAME, U4SLSMN.SLLC, U4CONST.C4NAME
FROM U4SLSMN INNER JOIN U4CONST ON U4SLSMN.SLNO = U4CONST.C4NAME
) AS P
WHERE P.ID BETWEEN 10 AND 30
The error I get is:
Selection error involving field *N.
Note that the JOIN query works correctly by itself, just not when it's run as a subquery.
How do I perform a join inside a subquery in DB2?
Works fine for me on v7.1 TR9
Here's what I actually ran:
select *
from ( select rownumber() over (order by vvname) as ID, idescr, vvname
from olsdta.ioritemmst
inner join olsdta.vorvendmst on ivndno = vvndno
) as P
where p.id between 10 and 30;
I much prefer the CTE version however:
with p as
( select rownumber() over (order by vvname) as ID, idescr, vvname
from olsdta.ioritemmst
inner join olsdta.vorvendmst on ivndno = vvndno
)
select *
from p
where p.id between 10 and 30;
Finally, note that at 7.1 TR11 (7.2 TR3), IBM added support of the LIMIT and OFFSET clauses. Your query could be re-done as follows:
SELECT
U4SLSMN.SLNO, U4SLSMN.SLNAME, U4SLSMN.SLLC, U4CONST.C4NAME
FROM U4SLSMN INNER JOIN U4CONST ON U4SLSMN.SLNO = U4CONST.C4NAME
ORDER BY U4SLSMN.SLNAME
LIMIT 20 OFFSET 9;
However, note that the LIMIT & OFFSET clauses are only supported in prepared or embedded SQL. You can't use them in STRSQL or STRQMQRY. I believe the "Run SQL Scripts" GUI interface does support them. Here's an article about LIMIT & OFFSET

TSQL invalid HAVING count

I am using SSMS 2008 and trying to use a HAVING statement. This should be a real simple query. However, I am only getting one record returned event though there are numerous duplicates.
Am I doing something wrong with the HAVING statement here? Or is there some other function that I could use instead?
select
address_desc,
people_id
from
dbo.address_view
where people_id is not NULL
group by people_id , address_desc
having count(*) > 1
sample data from address_view:
people_id address_desc
---------- ------------
Murfreesboro, TN 37130 F15D1135-9947-4F66-B778-00E43EC44B9E
11 Mohawk Rd., Burlington, MA 01803 C561918F-C2E9-4507-BD7C-00FB688D2D6E
Unknown, UN 00000 C561918F-C2E9-4507-BD7C-00FB688D2D6E
Jacksonville, NC 28546 FC7C78CD-8AEA-4C8E-B93D-010BF8E4176D
Memphis, TN 38133 8ED8C601-5D35-4EB7-9217-012905D6E9F1
44 Maverick St., Fitchburg, MA 8ED8C601-5D35-4EB7-9217-012905D6E9F1
The GROUP BY is going to lump your duplicates together into a single row.
I think instead, you want to find all people_id values with duplicate address_desc:
SELECT a.address_desc, a.people_id
FROM dbo.address_view a
INNER JOIN (SELECT address_desc
FROM dbo.address_view
GROUP BY address_desc
HAVING COUNT(*) > 1) t
ON a.address_desc = t.address_desc
using row_number and partition you can find the duplicate occurrences where row_num>1
select address_desc,
people_id,
row_num
from
(
select
address_desc,
people_id,
row_number() over (partition by address_desc order by address_desc) row_num
from
dbo.address_view
where people_id is not NULL
) x
where row_num>1

Simplified cross joins?

Let's sat I have a Table 'A' with rows:
A
B
C
D
Is there a simple way to do a cross join that creates
A 1
A 2
A 3
A 4
...
D 1
D 2
D 3
D 4
without creating a second table?
Something like:
SELECT *
FROM A
CROSS JOIN (1,2,3,4)
something like that should work, i guess
select * from A cross join (select 1 union all select 2 union all select 3 union all select 4) as tmp
you will create a second table, but you won't persist it.
The following would work for a table of any size (though I only tested it against 6 rows). It uses the ranking functions available in SQL Server 2005 and up, but the idea should be adaptible to any RDBMS.
SELECT ta.SomeColumn, cj.Ranking
from TableA ta
cross join (select row_number() over (order by SomeColumn) Ranking from TableA) cj
order by ta.SomeColumn, cj.Ranking
You should be able to achieve this via
select * from A cross join
(select 1
union all
select 2
union all
select 3
union all
select 4)