Tree Like Query On SQL Server - sql

i have a query join 4 tables
SELECT
a.Id AS KelompokInformasi, d.Name AS Domain, d.Id AS Dimension, e.Text AS Description FROM XBRLNamespaces a
INNER JOIN Hypercubes b
ON a.XBRLView_ViewId = b.XBRLView_ViewId
INNER JOIN HypercubeDimensionItems c
ON b.XBRLHypercubeId = c.XBRLHypercube_XBRLHypercubeId
INNER JOIN Items d
ON c.XBRLItem_ItemId = d.ItemId
INNER JOIN Labels e
ON d.ItemId = e.XBRLItem_ItemId
WHERE a.Id like '%AAKX%'
the query result is
KelompokInformasi Domain Dimension Description
AAKX JWAAKT dim_JWAAKT Jangka Waktu Aset
AAKX KOKOLT dim_KOKOLT Kolektibilitas
AAKX SNOUPL dim_SNOUPL Status Operasional Usaha Pihak Lawan
AAKX is a parent from the other data in Domain, Dimension, and Description.
So, i want to change the query and in the end have an output query result like this:
KelompokInformasi Domain Dimension Description
AAKX NULL NULL NULL
NULL JWAAKT dim_JWAAKT Jangka Waktu Aset
NULL KOKOLT dim_KOKOLT Kolektibilitas
NULL SNOUPL dim_SNOUPL Status Operasional Usaha Pihak Lawan

I think you must use Group by with cube and having. Or grouping sets.
http://technet.microsoft.com/en-us/library/bb522495(v=SQL.105).aspx

SELECT
'KelompokInformasi' =
CASE
WHEN a.Id like '%AAKX%' THEN a.Id
ELSE NULL
END,
'Domain' =
CASE
WHEN a.Id like '%AAKX%' THEN NULL
ELSE d.Name
END,
'Dimension' =
CASE
WHEN a.Id like '%AAKX%' THEN NULL
ELSE d.Id
END,
'Description' =
CASE
WHEN a.Id like '%AAKX%' THEN NULL
ELSE e.Text
END,
FROM XBRLNamespaces a
INNER JOIN Hypercubes b
ON a.XBRLView_ViewId = b.XBRLView_ViewId
INNER JOIN HypercubeDimensionItems c
ON b.XBRLHypercubeId = c.XBRLHypercube_XBRLHypercubeId
INNER JOIN Items d
ON c.XBRLItem_ItemId = d.ItemId
INNER JOIN Labels e
ON d.ItemId = e.XBRLItem_ItemId
WHERE a.Id like '%AAKX%'

You can use Common table Expression(CTE),ROW_NUMBER() and Same Case statement used as above:
WITH cte AS
SELECT
a.Id AS KelompokInformasi,d.Name AS DOMAIN,d.Id AS Dimension,e.Text AS Description ,
ROW_NUMBER() OVER (PARTITION BY a.Id ORDER BY a.ID) AS COL5
FROM XBRLNamespaces a
INNER JOIN Hypercubes b
ON a.XBRLView_ViewId = b.XBRLView_ViewId
INNER JOIN HypercubeDimensionItems c
ON b.XBRLHypercubeId = c.XBRLHypercube_XBRLHypercubeId
INNER JOIN Items d
ON c.XBRLItem_ItemId = d.ItemId
INNER JOIN Labels e
ON d.ItemId = e.XBRLItem_ItemId
WHERE a.Id LIKE '%AAKX%' )
SELECT CASE
WHEN COL5 >1 THEN NULL ELSE KelompokInformasi END AS KelompokInformasi,
CASE
WHEN COL5=1 THEN NULL ELSE DOMAIN END AS DOMAIN,
CASE
WHEN COL5=1 THEN NULL ELSE Dimension END AS Dimension,
CASE
WHEN COL5=1 THEN NULL ELSE Description END AS Description
FROM cte

Related

remove and sum duplicate row in sql, can anyone give me insight for my query?

My query are like this
SELECT
A."name" AS so_name,
CASE
WHEN COUNT(*) OVER (PARTITION BY A."name") > 1
THEN CONCAT('duplicate')
ELSE CONCAT('is unique')
END AS tags,
e.total_qty AS sc_qty,
(SELECT DISTINCT (COALESCE(e.amount_total) * COALESCE (ai.base_currency_rate, 1))
FROM account_invoice ai
JOIN invoice_sale_rel isr ON isr.invoice_id = ai.ID
WHERE isr.sale_id = e.ID) AS sc_total
FROM
sale_quotation A
JOIN
res_partner b ON b.ID = A.partner_id
JOIN
sale_order e ON e.quotation_id = A.ID
LEFT JOIN
res_users C ON C.ID = A.user_id
LEFT JOIN
res_partner d ON d.ID = C.partner_id
WHERE
A.STATE != 'cancel'
AND e.STATE != 'cancel'
AND e.is_merchant = TRUE
ORDER BY
A.NAME ASC
And this is the result:
I am expecting the result would be like this, and add another values too
You need SUM() and GROUP BY
SELECT
A."name" AS so_name,
'is unique' AS tags,
SUM(e.total_qty) AS sc_qty /*,
(SELECT DISTINCT (COALESCE(e.amount_total) * COALESCE (ai.base_currency_rate, 1))*/
FROM account_invoice ai
JOIN invoice_sale_rel isr ON isr.invoice_id = ai.ID
WHERE isr.sale_id = e.ID) AS sc_total
FROM
sale_quotation A
JOIN
res_partner b ON b.ID = A.partner_id
JOIN
sale_order e ON e.quotation_id = A.ID
LEFT JOIN
res_users C ON C.ID = A.user_id
LEFT JOIN
res_partner d ON d.ID = C.partner_id
WHERE
A.STATE != 'cancel'
AND e.STATE != 'cancel'
AND e.is_merchant = TRUE
GROUP BY
A.NAME
ORDER BY
A.NAME ASC

How can I count the same fields

I'm making a query to get the stages of a case. So Now I have three cases with 3 stages (the last stage inserted in the table user_case_stage).
SELECT DISTINCT ON (c.id)
c.id,
f.name
FROM schema.user a
JOIN schema.intern_user b ON a.id = b."userId"
JOIN schema.user_case c ON b.id = c."internUserId"
JOIN schema.user_case_stage d ON c.id = d."userCaseId"
JOIN schema.stage f ON d."stageId" = f.id
WHERE b.id = 1
ORDER BY c.id,d."createdAt" DESC
Result:
caseId stageName
1 "Pasive"
6 "Closed"
7 "Closed"
But I want something to count by stageName like this:
total stageName
1 "Pasive"
2 "Closed"
assumed your logic is correct , since you didn't provide any information, here is how you can do it:
SELECT
f.name
, count(distinct c.id) total
FROM schema.user a
JOIN schema.intern_user b ON a.id = b."userId"
JOIN schema.user_case c ON b.id = c."internUserId"
JOIN schema.user_case_stage d ON c.id = d."userCaseId"
JOIN schema.stage f ON d."stageId" = f.id
WHERE b.id = 1
group by f.name

My left join in oracle sql is not returning every element of the left table

i'm trying to get all the elements on the table B_ARTICULOS and make some calculations joining other tables (where some elements of B_ARTICULOS are not present) and I know I have to use a left join for that but I dont know what i'm doing wrong.
With this query I dont get every B_ARTICULOS, only those that are listed on the other tables
SELECT a.id, a.nombre,
CASE WHEN a.id IN dc.id_articulo THEN dc.cantidad ELSE 0 END CANTIDAD_COMPRAS,
CASE WHEN a.id IN dc.id_articulo THEN dc.cantidad * a.costo ELSE 0 END MONTO_COMPRAS,
CASE WHEN a.id IN dv.id_articulo THEN dv.cantidad ELSE 0 END CANTIDAD_VENTAS,
CASE WHEN a.id IN dv.id_articulo THEN dv.cantidad * a.precio ELSE 0 END MONTO_VENTAS
FROM B_ARTICULOS a
LEFT JOIN B_DETALLE_COMPRAS dc ON a.id = dc.id_articulo
JOIN B_COMPRAS c ON dc.id_compra = c.id
JOIN B_DETALLE_VENTAS dv ON dv.id_articulo = a.id
JOIN B_VENTAS v ON v.id = dv.id_venta
WHERE a.id IS NOT NULL;
The only explanation which I can see here is that you should be left joining to some of those other tables, beyond the second B_DETALLE_COMPRAS table. Assuming you would use left joins everywhere:
SELECT
a.id,
a.nombre,
CASE WHEN a.id IN dc.id_articulo THEN dc.cantidad ELSE 0 END CANTIDAD_COMPRAS,
CASE WHEN a.id IN dc.id_articulo THEN dc.cantidad * a.costo ELSE 0 END MONTO_COMPRAS,
CASE WHEN a.id IN dv.id_articulo THEN dv.cantidad ELSE 0 END CANTIDAD_VENTAS,
CASE WHEN a.id IN dv.id_articulo THEN dv.cantidad * a.precio ELSE 0 END MONTO_VENTAS
FROM B_ARTICULOS a
LEFT JOIN B_DETALLE_COMPRAS dc ON a.id = dc.id_articulo
LEFT JOIN B_COMPRAS c ON dc.id_compra = c.id
LEFT JOIN B_DETALLE_VENTAS dv ON dv.id_articulo = a.id
LEFT JOIN B_VENTAS v ON v.id = dv.id_venta
WHERE a.id IS NOT NULL;
You have to use left join too for other tables, like so:
...
FROM B_ARTICULOS a
LEFT JOIN B_DETALLE_COMPRAS dc ON a.id = dc.id_articulo
LEFT JOIN B_COMPRAS c ON dc.id_compra = c.id
LEFT JOIN B_DETALLE_VENTAS dv ON dv.id_articulo = a.id
LEFT JOIN B_VENTAS v ON v.id = dv.id_venta
...
Personally, I make subqueries for all the related tables that will be left joined to the main table. I grouped those tables then left join them to the main, like so:
...
FROM B_ARTICULOS a
LEFT JOIN (
SELECT dc.*
FROM B_DETALLE_COMPRAS dc
JOIN B_COMPRAS c ON dc.id_compra = c.id
) dc on a.id = dc.id_articulo
LEFT JOIN (
SELECT dv.*
FROM B_DETALLE_VENTAS dv
JOIN B_VENTAS v ON v.id = dv.id_venta
) dv ON dv.id_articulo = a.id
...

T-SQL force null value based on condition

This is my view
SELECT e.Text AS StatusText,
a.Created AS [DATE],
a.Username,
b.Name AS CustomerName,
c.Name AS ServiceName,
d.Message AS DeviationMessage
FROM dbo.StatusUpdate AS a
LEFT OUTER JOIN dbo.Customer AS b ON a.CustomerId = b.CustomerID
LEFT OUTER JOIN dbo.Service AS c ON a.ServiceId = c.ServiceID
LEFT OUTER JOIN dbo.Deviation AS d ON a.DeviationId = d.DeviationID
LEFT OUTER JOIN dbo.StatusText AS e ON a.Status = e.ID
What i would like to do is: When a.Status(int) is 2 or 3, i would like to force a.Username to show as NULL. How should i approach this?
Try this:
SELECT e.Text AS StatusText,
a.Created AS [DATE],
CASE a.status
WHEN 2 THEN NULL
WHEN 3 THEN NULL
ELSE a.Username
END,
b.Name AS CustomerName,
c.Name AS ServiceName,
d.Message AS DeviationMessage
FROM dbo.StatusUpdate AS a
LEFT OUTER JOIN dbo.Customer AS b ON a.CustomerId = b.CustomerID
LEFT OUTER JOIN dbo.Service AS c ON a.ServiceId = c.ServiceID
LEFT OUTER JOIN dbo.Deviation AS d ON a.DeviationId = d.DeviationID
LEFT OUTER JOIN dbo.StatusText AS e ON a.Status = e.ID
You could achieve this pretty easily with a case statment.
So something like
CASE WHEN Status = 3 THEN USERNAME IS NULL
This is untested but the idea is there.

SQL Server Query Returning Same Row Twice

I seem to be having trouble with the following query. It basically works, but I have a case where it is returning one row from mc_WorkoutDetails twice!
Here's the original query:
ALTER PROCEDURE [dbo].[mc_Workouts_GetActivities]
#WorkoutID bigint
AS
BEGIN
SET NOCOUNT ON
SELECT d.ID, a.Description,
CASE WHEN Reps = 0 THEN NULL ELSE Reps END AS Reps,
CASE WHEN Sets = 0 THEN NULL ELSE Sets END AS Sets,
CASE WHEN Minutes = 0 THEN NULL ELSE Minutes END AS Minutes,
d.Comments, c.Name AS Category, a.CategoryID,
(CASE WHEN v.ActivityID IS NULL THEN 0 ELSE 1 END) AS HasVideo,
a.ID AS ActivityID
FROM mc_WorkoutDetails d
INNER JOIN mc_Activities a ON d.ActivityID = a.ID
INNER JOIN mc_Activities_Categories c ON a.CategoryID = c.ID
LEFT OUTER JOIN mc_TrainerVideos v ON a.ID = v.ActivityID
WHERE (d.WorkoutID = #WorkoutID)
ORDER BY SortOrder, a.Description
RETURN ##ERROR
END
Then I tried changing:
INNER JOIN mc_Activities a ON d.ActivityID = a.ID
INNER JOIN mc_Activities_Categories c ON a.CategoryID = c.ID
To:
LEFT OUTER JOIN mc_Activities a ON d.ActivityID = a.ID
LEFT OUTER JOIN mc_Activities_Categories c ON a.CategoryID = c.ID
But that didn't seem to help. I still get the duplicate row.
Can anyone see what's happening?
What you can do is add a join back to the same table using a group to weed out the duplicate rows.
So add this to your join after FROM mc_WorkoutDetails d:
inner join (select [columns you want to select], max(id) id
from mc_WorkoutDetails
group by [columns you want to select] ) q on q.id = d.id
Let me know if that makes sense. Basically you are doing a distinct and getting the max id so you eliminate one of the rows in the join. You have to remember that even if you want there to be duplicates, they will be eliminated even if they are suppose to be there.
The full alter would be:
ALTER PROCEDURE [dbo].[mc_Workouts_GetActivities]
#WorkoutID bigint
AS
BEGIN
SET NOCOUNT ON
SELECT d.ID, a.Description,
CASE WHEN Reps = 0 THEN NULL ELSE Reps END AS Reps,
CASE WHEN Sets = 0 THEN NULL ELSE Sets END AS Sets,
CASE WHEN Minutes = 0 THEN NULL ELSE Minutes END AS Minutes,
d.Comments, c.Name AS Category, a.CategoryID,
(CASE WHEN v.ActivityID IS NULL THEN 0 ELSE 1 END) AS HasVideo,
a.ID AS ActivityID
FROM mc_WorkoutDetails d
inner join (select Reps, Sets, Comments, Minutes, max(id) id
from mc_WorkoutDetails
group by Reps, Sets, Comments, Minutes ) q on q.id = d.id
INNER JOIN mc_Activities a ON d.ActivityID = a.ID
INNER JOIN mc_Activities_Categories c ON a.CategoryID = c.ID
LEFT OUTER JOIN mc_TrainerVideos v ON a.ID = v.ActivityID
WHERE (d.WorkoutID = #WorkoutID)
ORDER BY SortOrder, a.Description
RETURN ##ERROR
END
Thanks for everyone's input. The general suggestions here were correct: I had two rows in the mc_workoutDetails table that referenced the same row in the mc_Activities table.
While the foreign key was part of a unique primary key, it was a compound key and so this column could contain duplicates as long as the other column in the key were different.