SQL Using join but without on Condition - sql

I am looking for someone to help by updating this sql statement, as I want to join two tables but without using " ON AD.[UID] = UI.[UID] " ?
SELECT AD.[AdsID] ,AD.[UID] ,AD.[Section] ,AD.[Category] ,AD.[Country] ,AD.[State] ,AD.[City] ,SUBSTRING([AdsTit],1,30)+'...' as AdsTit ,SUBSTRING([AdsDesc],1,85) as AdsDesc ,AD.[AdsPrice] ,AD.[Img1] ,AD.[Currency] ,AD.[Section] ,AD.[Currency] ,AD.[AdsDate] ,AD.[approvAds] ,UI.[approv]
FROM [ads] as AD JOIN UserInfo as UI ON AD.[UID] = UI.[UID]
where AD.[Country] = #Location AND AD.[approvAds]= 'Y' AND UI.[approv]='Y'
ORDER BY [AdsDate] DESC

You can move condition from 'on' to 'where', it works like inner join
SELECT AD.[AdsID] ,AD.[UID] ,AD.[Section] ,AD.[Category] ,AD.[Country] ,AD.[State] ,AD.[City] ,SUBSTRING([AdsTit],1,30)+'...' as AdsTit ,SUBSTRING([AdsDesc],1,85) as AdsDesc ,AD.[AdsPrice] ,AD.[Img1] ,AD.[Currency] ,AD.[Section] ,AD.[Currency] ,AD.[AdsDate] ,AD.[approvAds] ,UI.[approv]
FROM [ads] as AD, UserInfo as UI
where AD.[UID] = UI.[UID]
and AD.[Country] = #Location AND AD.[approvAds]= 'Y' AND UI.[approv]='Y'
ORDER BY [AdsDate] DESC

You can use the USING keyword instead of ON in your SQL query or use a natural join, which compares all the common columns in two tables itself without the on condition.
Query for your tables like this:
select AD.column1, AD.column2, UI.column1, UI.column2........
from ads AD join userinfo UI using(UID)
where AD.country='location' and AD.ApprovAds='y' and UI.approv='y'
order by Ads(date) desc
Or
select AD.column1, AD.column2, UI.column1, UI.column2........
from ads AD natural join userinfo UI
where AD.country='location' and AD.ApprovAds='y' and UI.approv='y'
order by Ads(date) desc

you want a cross join, don't recommend doing this as the performance is better on a join with a conditional statement.
That being said here is how you do it:
SELECT A.*, B.*
FROM A CROSS JOIN B
WHERE A.Id = B.AId
Just put the tables you need in place of A and B statements

Related

Too many columns in GROUP BY

I'm trying to aggregate some data, but I've a problem. There's my query (using 3 tables):
SELECT
ufc.counter_id,
gcrvf.goal_id,
gcrvf.date_of_visit,
ufc.utm_campaign,
ufc.utm_source,
ufc.utm_medium,
ufc.utm_content,
ufc.utm_term,
ufc.original_join_id,
max(gcrvf.last_update_time) AS last_update_time,
sum(gcrvf.conversions) AS conversions,
c.name AS counter_name,
c.owner_login AS owner_login,
c.status AS counter_status,
concat(g.goal_source,CAST('Goal','text')) AS metric_type,
multiIf(g.is_retargeting = 0,'non-retargeting',g.is_retargeting = 1,'retargeting',NULL) AS metric_key,
concat(g.name,' (',CAST(gcrvf.goal_id,'String'),')') AS metric_name
FROM connectors_yandex_metrika.goal_conversions_report_v_final AS gcrvf
INNER JOIN connectors_yandex_metrika.utm_for_collect AS ufc ON gcrvf.counter_id = ufc.counter_id
LEFT JOIN connectors_yandex_metrika.counter AS c ON gcrvf.counter_id = c.id
LEFT JOIN connectors_yandex_metrika.goal AS g ON gcrvf.goal_id = g.id
WHERE
((gcrvf.utm_campaign = ufc.utm_campaign) OR (ufc.utm_campaign IS NULL))
AND ((gcrvf.utm_source = ufc.utm_source) OR (ufc.utm_source IS NULL))
AND ((gcrvf.utm_medium = ufc.utm_medium) OR (ufc.utm_medium IS NULL))
AND ((gcrvf.utm_content = ufc.utm_content) OR (ufc.utm_content IS NULL))
AND ((gcrvf.utm_term = ufc.utm_term ) OR (ufc.utm_term IS NULL))
GROUP BY
ufc.counter_id,
gcrvf.date_of_visit,
gcrvf.goal_id,
ufc.utm_campaign,
ufc.utm_source,
ufc.utm_medium,
ufc.utm_content,
ufc.utm_term,
ufc.original_join_id,
c.name,
c.owner_login,
c.status,
metric_type,
metric_key,
metric_name
I have to GROUP BY by almost all columns. Is it a real problem?
Columns ufc.original_join_id, c.name,c.owner_login, c.status, metric_type, metric_key,metric_name are not necessary here. I added them to group by just because I need these columns. And I want to ask: any way to make it more abbreviated? Any ways to avoid unnecessary columns from group by? Or it's okay?
And my second question: does ClickHouse cache right table when we use JOINs? So I always should put huge table as left table?
All columns are required in the group by. It is not possible to leaf some columns out which where mentioned as select columns.
Depending on your indexed columns you can improve the speed of the query. You should try to make an index on the key columns.
The Database will handle the cache logic for you. Depending on how often you execute the query.

Joining a Query and sub-query

I'm trying to join a query and a sub-query in Access but haven't the faintest idea on how to do that. Rather than saving the sub-query as a different query and then joining it to the main query.
Main query (with reference to sub-query):
SELECT tb200_IraDataIn.tb200_niarnum, tb206_IraAccount.tb206_IraAccDesc,
tb206_IraAccount.tb206_IraAccNum, tb15_Securities.tb15_IsActiveRegister,
tb15_Securities.tb15_NiarDesc, tb15_Securities.tb15_ManpikID, tb200_IraDataIn.tb200_Shovi, tb10_Afik.tb10_InvestTool,
tb206_IraAccount.tb206_IsActive, tb200_IraDataIn.tb200_Shovi,
tb200_IraDataIn.tb200_Shovi/SubQuery1.SumOftb200_Shovi AS Expr1
FROM SubQuery1
INNER JOIN (tb10_Afik
INNER JOIN (tb15_Securities
INNER JOIN (tb206_IraAccount
INNER JOIN tb200_IraDataIn
ON tb206_IraAccount.tb206_IraAccNum = tb200_IraDataIn.tb200_accountNumber)
ON tb15_Securities.tb15_NiarID = tb200_IraDataIn.tb200_niarnum)
ON (tb10_Afik.tb10_AfikID = tb200_IraDataIn.tb200_afik) AND (tb10_Afik.tb10_Erp =tb200_IraDataIn.tb200_ERP))
ON SubQuery1.tb206_IraAccNum = tb206_IraAccount.tb206_IraAccNum
WHERE (((tb15_Securities.tb15_IsActiveRegister)=Yes) AND ((tb10_Afik.tb10_InvestTool)=1
Or (tb10_Afik.tb10_InvestTool)=4 Or (tb10_Afik.tb10_InvestTool)=21 Or
(tb10_Afik.tb10_InvestTool)=3) AND ((tb206_IraAccount.tb206_IsActive)=Yes) AND
(([tb200_IraDataIn].[tb200_Shovi]/[SubQuery1].[SumOftb200_Shovi])>0.1));
subquery (saved as SubQuery1):
SELECT tb206_IraAccount.tb206_IraAccDesc, tb206_IraAccount.tb206_IraAccNum, Sum(tb200_IraDataIn.tb200_Shovi) AS SumOftb200_Shovi
FROM tb206_IraAccount
INNER JOIN tb200_IraDataIn ON tb206_IraAccount.tb206_IraAccNum = tb200_IraDataIn.tb200_accountNumber
WHERE (((tb206_IraAccount.tb206_IsActive)=Yes))
GROUP BY tb206_IraAccount.tb206_IraAccDesc, tb206_IraAccount.tb206_IraAccNum;
How can I put the sql statement of the sub-query inside the same Sql statement of the main query, unlike now?
Thanks!
Nest between parentheses. Nothing else in the main query changes.
SELECT
...
FROM (SELECT tb206_IraAccount.tb206_IraAccDesc, tb206_IraAccount.tb206_IraAccNum, Sum(tb200_IraDataIn.tb200_Shovi) AS SumOftb200_Shovi
FROM tb206_IraAccount
INNER JOIN tb200_IraDataIn ON tb206_IraAccount.tb206_IraAccNum = tb200_IraDataIn.tb200_accountNumber
WHERE (((tb206_IraAccount.tb206_IsActive)=Yes))
GROUP BY tb206_IraAccount.tb206_IraAccDesc, tb206_IraAccount.tb206_IraAccNum) AS SubQuery1
...

Need help in optimizing sql query

I am new to sql and have created the below sql to fetch the required results.However the query seems to take ages in running and is quite slow. It will be great if any help in optimization is provided.
Below is the sql query i am using:
SELECT
Date_trunc('week',a.pair_date) as pair_week,
a.used_code,
a.used_name,
b.line,
b.channel,
count(
case when b.sku = c.sku then used_code else null end
)
from
a
left join b on a.ma_number = b.ma_number
and (a.imei = b.set_id or a.imei = b.repair_imei
)
left join c on a.used_code = c.code
group by 1,2,3,4,5
I would rewrite the query as:
select Date_trunc('week',a.pair_date) as pair_week,
a.used_code, a.used_name, b.line, b.channel,
count(*) filter (where b.sku = c.sku)
from a left join
b
on a.ma_number = b.ma_number and
a.imei in ( b.set_id, b.repair_imei ) left join
c
on a.used_code = c.code
group by 1,2,3,4,5;
For this query, you want indexes on b(ma_number, set_id, repair_imei) and c(code, sku). However, this doesn't leave much scope for optimization.
There might be some other possibilities, depending on the tables. For instance, or/in in the on clause is usually a bad sign -- but it is unclear what your intention really is.

Combine two queries, one based upon the other, into one

I have two queries, one based partly on the other. Is there a way of combining them into a single query?
SELECT tblIssues.*, tblIssues.NewsletterLookup
FROM tblIssues
WHERE (((tblIssues.NewsletterLookup)=5));
SELECT tblArea.ID, tblArea.AreaName
FROM tblArea LEFT JOIN Query2 ON tblArea.ID = Query2.[AreaLookup]
WHERE (((tblArea.Dormant)=False) AND ((Query2.tblIssues.NewsletterLookup) Is Null));
If you want to do this in a single query without Query2, you can use the equivalent SQL from Query2 as a subquery in your second example:
SELECT a.ID, a.AreaName
FROM
tblArea AS a
LEFT JOIN
(
SELECT i.*
FROM tblIssues AS i
WHERE i.NewsletterLookup=5
) AS sub
ON a.ID = sub.[AreaLookup]
WHERE
a.Dormant=False
AND sub.NewsletterLookup Is Null;
You ment to perform a JOIN like
SELECT ti.*, tblArea.ID, tblArea.AreaName
FROM tblArea ta
LEFT JOIN tblIssues ti ON ta.ID = ti.[AreaLookup]
WHERE (ti.NewsletterLookup=5 OR ti.NewsletterLookup Is Null)
AND ta.Dormant=False;

Query to return SINGLE DISTINCT row

I have the query below working, the thing is I need to only list each unique "VolumeSerialNumber0" once. There's no shortage of questions and approaches to this problem on SO but they suggest using subqueries and group by clause, but when I try to do that I get an error "columnname is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
I feel like it has to be close I'm just not getting the magical syntax perfectly correct.
SELECT
dbo.v_R_System.Netbios_Name0,
dbo.v_GS_LOGICAL_DISK.TimeStamp,
dbo.v_GS_LOGICAL_DISK.Description0,
dbo.v_GS_LOGICAL_DISK.DeviceID0,
dbo.v_GS_LOGICAL_DISK.DriveType0,
dbo.v_GS_LOGICAL_DISK.Name0,
dbo.v_GS_LOGICAL_DISK.SystemName0,
dbo.v_GS_LOGICAL_DISK.VolumeName0,
dbo.v_GS_LOGICAL_DISK.VolumeSerialNumber0,
dbo.v_GS_PARTITION.Size0,
dbo.v_GS_LOGICAL_DISK.FileSystem0
FROM
dbo.v_R_System
INNER JOIN dbo.v_GS_LOGICAL_DISK
ON dbo.v_R_System.ResourceID = dbo.v_GS_LOGICAL_DISK.ResourceID
INNER JOIN dbo.v_GS_PARTITION
ON dbo.v_GS_LOGICAL_DISK.ResourceID = dbo.v_GS_PARTITION.ResourceID
SELECT
MAX(S.Netbios_Name0),
MAX(L.TimeStamp),
MAX(L.Description0),
MAX(L.DeviceID0),
MAX(L.DriveType0),
MAX(L.Name0),
MAX(L.SystemName0),
MAX(L.VolumeName0),
L.VolumeSerialNumber0,
MAX(P.Size0),
MAX(L.FileSystem0)
FROM
dbo.v_R_System S
INNER JOIN dbo.v_GS_LOGICAL_DISK L
ON S.ResourceID = L.ResourceID
INNER JOIN dbo.v_GS_PARTITION P
ON L.ResourceID = P.ResourceID
GROUP BY
L.VolumeSerialNumber0