using sub query in select clause - sql

I have the following SQL query which I want to use the value of public.account.phone_number for the LIKE clause of the sub query.
Unfortunately something is not working right since the query is returning 0 for total_responses when I replace '%public.account.phone_number' which a phone number in the database I get the correct value.
SELECT
public.email_account.email,
public.account.password,
public.ad.city,
public.ad.state,
public.ad.age,
public.ad.hotel,
public.ad.insert_time,
public.ad.ad_url,
public.ad.active,
public.ad.on_page,
public.ad.paid,
public.account.phone_number,
(SELECT COUNT(*) FROM public.match where match_id LIKE '%public.account.phone_number') AS total_responses
FROM
public.account
INNER JOIN public.ad
ON public.account.id = public.ad.account_id
INNER JOIN public.email_account
ON public.account.email_account_id = public.email_account.id
ORDER BY
ad.active ASC,
on_page DESC

I guess you want to do concatenation with the outer field phone_number.
Try this:
SELECT
public.email_account.email,
public.account.password,
public.ad.city,
public.ad.state,
public.ad.age,
public.ad.hotel,
public.ad.insert_time,
public.ad.ad_url,
public.ad.active,
public.ad.on_page,
public.ad.paid,
public.account.phone_number,
(SELECT COUNT(*) FROM public.match where match_id LIKE '%' || public.account.phone_number) AS total_responses
FROM
public.account
INNER JOIN public.ad
ON public.account.id = public.ad.account_id
INNER JOIN public.email_account
ON public.account.email_account_id = public.email_account.id
ORDER BY
ad.active ASC,
on_page DESC

Related

Use count and group by in a joins table?

Here is my query and I want to add the "count of SalID group by OFID" and store the result in the same table.
SELECT
T_OF.OFID,
T_OF.OFDateDPrev, T_OF.OFDateFPrev,
T_OF_User.OFUserID,
T_OF_User.SalID
INTO T_tracing
FROM T_OF
INNER JOIN T_OF_User
ON T_OF_User.OFID = T_OF.OFID
I tried this:
SELECT
T_OF.OFID,
T_OF.OFDateDPrev, T_OF.OFDateFPrev,
T_OF_User.OFUserID,
Count (SalID) FROM T_OF_User GROUP BY OFID
INTO T_tracing
FROM T_OF
INNER JOIN T_OF_User
ON T_OF_User.OFID = T_OF.OFID
But I have an error message. Any help please?
I think you want a window function:
SELECT T_OF.OFID, T_OF.OFDateDPrev, T_OF.OFDateFPrev, T_OF_User.OFUserID,
Count(SalID) OVER (PARTITION BY T_OF.OFID) as cnt
INTO T_tracing
FROM T_OF JOIN
T_OF_User
ON T_OF_User.OFID = T_OF.OFID;
You also need to give the result of the expression a name for T_Tracing.

SQL-Query (with subquery, group and order by) optimization

coud you help me optimizing the following statement. It has a bad prerformance when dealing with huge amount of data (in my case 3Mio Messages and 25Mio MessageWorkItems).
Does anybody have any suggestions? Thank you in advance.
select distinct msg.id, msgWorkItem_1.description
from message msg
left outer join message_work_item msgWorkItem_1 on msg.id=msgWorkItem_1.message_id
and ( msgWorkItem_1.id in (
select max(msgWorkItem_2.id)
from message_work_item msgWorkItem_2
inner join message_work_item_type msgWorkItem_Type on msgWorkItem_2.message_work_item_type_id=msgWorkItem_Type.id
where
msgWorkItem_2.creation_type= 'mobile'
and msgWorkItem_2.description is not null
and msgWorkItem_Type.code <> 'sent-to-app-manually'
-- Is it possible to avoid this correlation to the outer query ? )
and msgWorkItem_2.message_id = msg.id)
)
where msg.deactivation_time > ?
order by msgWorkItem_1.description asc
STEP 1 : Lay out the query so I have any hope of reading it
SELECT
DISTINCT
msg.id,
msgWorkItem_1.description
FROM
message msg
LEFT OUTER JOIN
message_work_item AS msgWorkItem_1
ON msgWorkItem_1.message_id = msg.id
AND msgWorkItem_1.id =
(
SELECT
MAX(msgWorkItem_2.id)
FROM
message_work_item AS msgWorkItem_2
INNER JOIN
message_work_item_type AS msgWorkItem_Type
ON msgWorkItem_2.message_work_item_type_id=msgWorkItem_Type.id
WHERE
msgWorkItem_2.creation_type= 'mobile'
AND msgWorkItem_2.description IS NOT NULL
AND msgWorkItem_Type.code <> 'sent-to-app-manually'
-- Is it possible to avoid this correlation to the outer query ?
AND msgWorkItem_2.message_id = msg.id
)
WHERE
msg.deactivation_time > ?
ORDER BY
msgWorkItem_1.description ASC
STEP 2 : rewrite using analytic functions instead of MAX()
SELECT
DISTINCT
message.id,
message_work_item_sorted.description
FROM
message
LEFT OUTER JOIN
(
SELECT
message_work_item.message_id,
message_work_item.description,
ROW_NUMBER() OVER (PARTITION BY message_work_item.message_id
ORDER BY message_work_item.id DESC
)
AS row_ordinal
FROM
message_work_item
INNER JOIN
message_work_item_type
ON message_work_item.message_work_item_type_id = message_work_item_type.id
WHERE
message_work_item.creation_type= 'mobile'
AND message_work_item.description IS NOT NULL
AND message_work_item_type.code <> 'sent-to-app-manually'
)
message_work_item_sorted
ON message_work_item_sorted.message_id = message.id
AND message_work_item_sorted.row_ordinal = 1
WHERE
message.deactivation_time > ?
ORDER BY
message_work_item_sorted.description ASC
With more information we could probably help further, but as you gave no definition of the tables, constraints, or business logic, this is just a re-write of what you're already implemented.
For example, I strongly doubt you need the DISTINCT (provided that the id columns in your tables are unique).

Subquery returned more than 1 value - MS SQL

select Id,Prayaseeid, name,Gender,
(select name from tb_Category where id = Category) AS Category,
ideadescription,Domain,ProjectTerms,ProjectStartDate,Amountsanctioned,
(select Amount from tb_innovatorDisbursement where tbid ='TBINO1111A' and
applyingforcycle='1') AS AmountDisbursed,
projectstatus,projectoutcome
from tb_innovator
where tbid='TBINO1111A 'and applyingforcycle='1'
Use TOP to Limit rows to 1,
The Select queries in parenthesis resulting in more than one record
select Id,Prayaseeid, name,Gender,
(select TOP(1) name from tb_Category where id = Category) AS Category,
ideadescription,Domain,ProjectTerms,ProjectStartDate,Amountsanctioned,
(select TOP(1) Amount
from tb_innovatorDisbursement where tbid ='TBINO1111A' and applyingforcycle='1') AS AmountDisbursed,
projectstatus,projectoutcome from tb_innovator
where tbid='TBINO1111A 'and applyingforcycle='1'
You need to test your sub queries for the where clause to make sure the values you are searching do not have multiple records. I would use (Top 1 ) for any column other than the Id column assuming the Id column must be unique as the name suggests.
Update query
select ti.Id,
ti.Prayaseeid,
ti.name,
ti.Gender,
(select TOP(1) name from tb_Category where id = ti.Category) AS Category,
ti.ideadescription,
ti.Domain,
ti.ProjectTerms,
ti.ProjectStartDate,
ti.Amountsanctioned,
tid.Amount AS AmountDisbursed,
ti.projectstatus,
ti.projectoutcome
from tb_innovator ti
INNER JOIN tb_innovatorDisbursement tid ON tid.Tbid = ti.tbid
AND tid.applyingforcycle='1'
where ti.tbid='TBINO1111A 'and ti.applyingforcycle='1'
Perhaps you should use JOIN:
select i.Id, i.Prayaseeid, i.name, i.Gender, c.Category,
i.ideadescription, i.Domain, i.ProjectTerms, i.ProjectStartDate, i.Amountsanctioned,
id.Amount from tb_innovatorDisbursement
i.projectstatus, i.projectoutcome
from tb_innovator i left join
tb_Category c
on i.category = c.id left join
tb_innovatorDisbursement id
on id.tbid = i.dbid and id.applyingforcycle = '1'
where i.tbid = 'TBINO1111A 'and i.applyingforcycle = '1';
Note that all column names are qualified as well, indicating what table they come from.

Not able to apply join in sql query

i want to add the join "JOIN {User}
ON {Deck}.[CreatedBy] = {User}.[Id]" in following query. I tried many combination but not succeeded. i want to fetch Name from User table
SELECT #CampaignQueryFilterString AS [Selected],
{Deck}.[Id], {Deck}.[Name],
{User}.[Name],
{Deck}.[TableOfContentId], {Deck}.[CreatedBy],
{Deck}.[LastModifiedOn], {Deck}.[ExpiryDate],s1.[Count]
FROM {Deck}
JOIN
(
SELECT {Deck}.[Id],
LISTAGG( {TagValue}.[Id], ',' ) WITHIN GROUP (ORDER BY {TagValue}.[TagCategoryId] ) AS Tags
FROM {Deck}
JOIN {AssociatedDeckTags}
ON {AssociatedDeckTags}.[DeckId] = {Deck}.[Id]
JOIN {TagValue}
ON {AssociatedDeckTags}.[TagValueId] = {TagValue}.[Id]
WHERE {Deck}.[IsPublished] = 1
AND {Deck}.[IsActive] = 1 AND {Deck}.[ReplacedByDeckId] IS NULL
AND {Deck}.[TableOfContentId] IN #TableOfContentIdFilterString
AND {Deck}.[ContentFileTypeId] IN #AllowedContentType
AND {Deck}.[ExpiryDate] > SYSDATE
GROUP BY {Deck}.[Id]
) DeckView
ON {Deck}.[Id] = DeckView.Id
JOIN(
SELECT COUNT(*) AS [Count], {DeckGroup}.[DeckId] AS [S1DeckId]
FROM {DeckGroup}
JOIN {Slide} ON {Slide}.[DeckGroupId] = {DeckGroup}.[Id]
GROUP BY {DeckGroup}.[DeckId]
) s1 ON s1.[S1DeckId] = {Deck}.[Id]
#RegexString
#SearchFilter
#CreatedBy
GROUP BY
{Deck}.[Id], {Deck}.[Name], {Deck}.[TableOfContentId],
{Deck}.[CreatedOn], {Deck}.[CreatedBy],
{Deck}.[LastModifiedOn], {Deck}.[ExpiryDate],
{Deck}.[NumOfPreviews], {Deck}.[NumOfDownloads],s1.[Count]
ORDER BY #Orderby
Looks like simply join, please try the below query (using your notation). I added left join and in group by clause - {User}.[Name]. Optionally you can use some aggregating function for {User}.[Name] - max(), listagg() and remove it from group by clause.
SELECT #CampaignQueryFilterString AS [Selected],
{Deck}.[Id], {Deck}.[Name], {User}.[Name], {Deck}.[TableOfContentId],
{Deck}.[CreatedBy], {Deck}.[LastModifiedOn], {Deck}.[ExpiryDate], s1.[Count]
FROM {Deck}
JOIN DeckView ON {Deck}.[Id] = DeckView.Id -- subquery1
JOIN s1 ON s1.[S1DeckId] = {Deck}.[Id] -- subquery2
LEFT JOIN {User} ON {Deck}.[CreatedBy] = {User}.[Id] -- <-- add join here
#RegexString
#SearchFilter
#CreatedBy
GROUP BY
{Deck}.[Id], {Deck}.[Name], {User}.[Name], -- <-- add column here
{Deck}.[TableOfContentId], {Deck}.[CreatedOn],
{Deck}.[CreatedBy], {Deck}.[LastModifiedOn],
{Deck}.[ExpiryDate], {Deck}.[NumOfPreviews],
{Deck}.[NumOfDownloads], s1.[Count]
ORDER BY #Orderby
You didn't show your tries, so we don't know if there was an error or undesired result. With this form of question that is all I can help. Also USER is one of Oracle Reserved Words, it's better to avoid using it as alias, variable name etc.

Column is invalid in the ORDER BY clause because it is not contained in either an aggregate function or the GROUP BY clause

Ok here's my View (vw_LiftEquip)
SELECT dbo.tbl_equip_swl_unit.unit_id,
dbo.tbl_equip_swl_unit.unit_name,
dbo.tbl_equip_swl_unit.archived,
dbo.tbl_categories.category_id,
dbo.tbl_categories.categoryName,
dbo.tbl_categories.parentCategory,
dbo.tbl_categories.sub_category,
dbo.tbl_categories.desc_category,
dbo.tbl_categories.description,
dbo.tbl_categories.miscellaneous,
dbo.tbl_categories.category_archived,
dbo.tbl_equip_swl_unit.unit_name AS Expr1,
dbo.tbl_categories.categoryName AS Expr2,
dbo.tbl_categories.description AS Expr3,
dbo.tbl_equip_depts.dept_name,
dbo.tbl_equip_man.man_name,
dbo.tbl_Lifting_Gear.e_defects AS Expr7,
dbo.tbl_Lifting_Gear.e_defects_desc AS Expr8,
dbo.tbl_Lifting_Gear.e_defects_date AS Expr9,
dbo.tbl_equipment.equipment_id,
dbo.tbl_equipment.e_contract_no,
dbo.tbl_equipment.slID,
dbo.tbl_equipment.e_entered_by,
dbo.tbl_equipment.e_serial,
dbo.tbl_equipment.e_model,
dbo.tbl_equipment.e_description,
dbo.tbl_equipment.e_location_id,
dbo.tbl_equipment.e_owner_id,
dbo.tbl_equipment.e_department_id,
dbo.tbl_equipment.e_manafacture_id,
dbo.tbl_equipment.e_manDate1,
dbo.tbl_equipment.e_manDate2,
dbo.tbl_equipment.e_manDate3,
dbo.tbl_equipment.e_dimensions,
dbo.tbl_equipment.e_test_no,
dbo.tbl_equipment.e_firstDate1,
dbo.tbl_equipment.e_firstDate2,
dbo.tbl_equipment.e_firstDate3,
dbo.tbl_equipment.e_prevDate1,
dbo.tbl_equipment.e_prevDate2,
dbo.tbl_equipment.e_prevDate3,
dbo.tbl_equipment.e_insp_frequency,
dbo.tbl_equipment.e_swl,
dbo.tbl_equipment.e_swl_unit_id,
dbo.tbl_equipment.e_swl_notes,
dbo.tbl_equipment.e_cat_id,
dbo.tbl_equipment.e_sub_id,
dbo.tbl_equipment.e_parent_id,
dbo.tbl_equipment.e_last_inspector,
dbo.tbl_equipment.e_last_company,
dbo.tbl_equipment.e_deleted AS Expr11,
dbo.tbl_equipment.e_deleted_desc AS Expr12,
dbo.tbl_equipment.e_deleted_date AS Expr13,
dbo.tbl_equipment.e_deleted_insp AS Expr14,
dbo.tbl_Lifting_Gear.e_defects_action AS Expr15,
dbo.tbl_equipment.e_rig_location,
dbo.tbl_Lifting_Gear.e_add_type AS Expr17,
dbo.tbl_Lifting_Gear.con_id,
dbo.tbl_Lifting_Gear.lifting_date,
dbo.tbl_Lifting_Gear.lifting_ref_no,
dbo.tbl_Lifting_Gear.e_id,
dbo.tbl_Lifting_Gear.inspector_id,
dbo.tbl_Lifting_Gear.lift_testCert,
dbo.tbl_Lifting_Gear.lift_rig_location,
dbo.tbl_Lifting_Gear.inspected,
dbo.tbl_Lifting_Gear.lifting_through,
dbo.tbl_Lifting_Gear.liftingNDT,
dbo.tbl_Lifting_Gear.liftingTest,
dbo.tbl_Lifting_Gear.e_defects,
dbo.tbl_Lifting_Gear.e_defects_desc,
dbo.tbl_Lifting_Gear.e_defects_date,
dbo.tbl_Lifting_Gear.e_defects_action,
dbo.tbl_Lifting_Gear.lift_department_id,
dbo.tbl_Lifting_Gear.lifting_loc
FROM dbo.tbl_equipment
INNER JOIN dbo.tbl_equip_swl_unit
ON dbo.tbl_equipment.e_swl_unit_id = dbo.tbl_equip_swl_unit.unit_id
INNER JOIN dbo.tbl_categories
ON dbo.tbl_equipment.e_cat_id = dbo.tbl_categories.category_id
INNER JOIN dbo.tbl_equip_depts
ON dbo.tbl_equipment.e_department_id = dbo.tbl_equip_depts.dept_id
INNER JOIN dbo.tbl_equip_man
ON dbo.tbl_equipment.e_manafacture_id = dbo.tbl_equip_man.man_id
INNER JOIN dbo.vwSubCategory
ON dbo.tbl_equipment.e_sub_id = dbo.vwSubCategory.category_id
INNER JOIN dbo.vwDescCategory
ON dbo.tbl_equipment.e_cat_id = dbo.vwDescCategory.category_id
INNER JOIN dbo.tbl_Lifting_Gear
ON dbo.tbl_equipment.equipment_id = dbo.tbl_Lifting_Gear.e_id
And here's the select statement with subquery that I am using:
SELECT *
FROM vw_LiftEquip
WHERE lifting_loc = ? AND
con_id = ? AND
EXPR11 =
'N'(
SELECT MAX(lifting_date) AS maxLift
FROM vw_LiftEquip
WHERE e_id = equipment_id
)
ORDER BY lifting_ref_no,
category_id,
e_swl,
e_serial
I get the error :
Column "vw_LiftEquip.category_id" is invalid in the ORDER BY clause because it is not contained in either an aggregate function or the GROUP BY clause.
Can't see why its returning that error, this is admittedly the first time I've ran a subquery on such a complex view, and I am a bit lost, thanks in advance for any help. I have looked through the similar posts and can find no answers to this one, sorry if I am just being dumb.
You are missing AND between EXPR11 = 'N' and (SELECT MAX(...
Otherwise, it looks OK. MAX without GROUP BY is allowed if you have no other columns in the SELECT
Update: #hvd also noted that you have nothing to compare to MAX(lifting_date). See comment
Update 2,
SELECT *
FROM vw_LiftEquip v1
CROSS JOIN
(
SELECT MAX(lifting_date) AS maxLift
FROM vw_LiftEquip
WHERE e_id = equipment_id
) v2
WHERE v1.lifting_loc = ? AND
v1.con_id = ? AND
v1.EXPR11 = 'N'
ORDER BY v1.lifting_ref_no,
v1.category_id,
v1.e_swl,
v1.e_serial