I'm quite new to SQL server and basically I have this query that uses two table and I was wondering if there's an easy way to shorten the code, the repeating of the table names looks pretty bad.
SELECT
dbo.atbl_Sales_OrdersLines.OrderID, dbo.atbl_Sales_OrdersLines.Created,
dbo.atbl_Sales_OrdersLines.CreatedBy, dbo.atbl_Sales_OrdersLines.Updated,
dbo.atbl_Sales_OrdersLines.UpdatedBy,
dbo.atbl_Sales_OrdersLines.CUT, dbo.atbl_Sales_OrdersLines.CDL,
dbo.atbl_Sales_OrdersLines.Domain, dbo.atbl_Sales_OrdersLines.ProductID,
dbo.atbl_Sales_OrdersLines.Amount, dbo.atbl_Sales_Products.ProductName,
dbo.atbl_Sales_Products.Supplier, dbo.atbl_Sales_Products.Quantity AS TotalQuantity,
dbo.atbl_Sales_Products.Price, dbo.atbl_Sales_OrdersLines.PrimKey
FROM
dbo.atbl_Sales_OrdersLines
INNER JOIN
dbo.atbl_Sales_Products ON dbo.atbl_Sales_OrdersLines.ProductID = dbo.atbl_Sales_Products.ProductID
There has to be an easier way to do this. Thank you.
Use tables alias to shorten that code:
SELECT
ol.OrderID,
ol.Created, ol.CreatedBy, ol.Updated, ol.UpdatedBy,
ol.CUT, ol.CDL,
ol.Domain, ol.ProductID, ol.Amount,
p.ProductName, p.Supplier, p.Quantity AS TotalQuantity, p.Price,
ol.PrimKey
FROM
dbo.atbl_Sales_OrdersLines ol
INNER JOIN
dbo.atbl_Sales_Products p ON ol.ProductID = p.ProductID
The ol and p are table alias that you can choose - I recommend choosing something that is "intuitive", e.g. "ol" for "Order Lines", "p" for "Product" - that makes reading (and understanding) your SQL code much easier
Related
I'm trying to build a query in MS Access and having an issue figuring out the best way to build it. What I'm trying to do is is make sure all the Higher retails match within a set of matching pack numbers. For example:
PackNum Prefix Retail
6451618 DF 37.99
6451618 SK 37.99
6451618 VJ 34.99
6451618 SG 37.99
One of the group is off and I want the query to show it.
I was attempting to use something like this to have check but I'm not getting the results I'm looking for
IIf([dbo_PIC704Current]![PackNum]=[dbo_PIC704Current]![PackNum]
And [dbo_PIC704Current]![Ret2]<>[dbo_PIC704Current]![Ret2],True,False)
Any help or push in the right direction would be greatly appreciated!
-Deke
SELECT dbo_pic704current.packnum
, Min(dbo_pic704current.Ret2) AS LowRet2
, Max(dbo_pic704current.Ret2) AS HighRet2
, dbo_CatalogInfo.MediaId
, dbo_pic704current.DiscountReasonCode
, dbo_CatalogInfo.Brand
FROM dbo_pic704current INNER JOIN dbo_CatalogInfo ON (dbo_pic704current.year =
dbo_CatalogInfo.mailyear) AND (dbo_pic704current.catid = dbo_CatalogInfo.catalog)
WHERE (((dbo_CatalogInfo.MediaId)='CAT Catalog'))
GROUP BY dbo_pic704current.packnum, dbo_CatalogInfo.MediaId,
dbo_pic704current.DiscountReasonCode, dbo_CatalogInfo.Brand, dbo_pic704current.Year
HAVING (((Min(dbo_pic704current.Ret2))<>Max([Ret2])))
ORDER BY dbo_pic704current.packnum;
Your existing solution using aggregation is likely to yield better performance, but to offer an alternative, here is an example using a correlated subquery:
select
pc.packnum, pc.ret2, ci.mediaid, pc.discountreasoncode, ci.brand
from
dbo_pic704current pc inner join dbo_cataloginfo ci on
pc.year = ci.mailyear and pc.catid = ci.catalog
where
ci.mediaid = 'cat catalog' and exists
(select 1 from dbo_pic704current t where t.packnum = pc.packnum and t.ret2 > pc.ret2)
order by
pc.packnum
I'm hoping to find a way to sniff out potentially inefficient T-SQL within stored procedures, in this case detecting not just cursors in stored procedures, but preferably nested cursors.
With the script below based on sys.dm_sql_referenced_entities, from a given starting stored procedure I can see a recursive downstream call stack, including a column indicating whether the text CURSOR was found within the procedure definition.
This is helpful, but it isn't capable of telling me:
whether more than one cursor exists within a procedure
whether nested cursors are used (and of course, the truly perfect solution for that would also have to detect a call to stored procedure containing a cursor, from within a cursor)
Being able to do this I think is probably beyond the abilities of querying sys tables, and involves parsing the SQL itself - does anyone know of a technique or tool that could accomplish this, or perhaps an entirely different approach that could tell me the same information.
DECLARE #procname varchar(30)
SET #procname='dbo.some_root_procedure_name'
;WITH CTE([DB],[OBJ],[INDENTED_OBJ],[SCH],[lvl],[indexof_cursor],[referenced_object_definition])
AS
(
SELECT referenced_database_name AS [DB],referenced_entity_name AS [OBJ],
cast(space(0) + referenced_entity_name as varchar(max)) AS [INDENTED_OBJ],
referenced_schema_name AS [SCH],0 AS [lvl]
,charindex('cursor',object_definition(referenced_id)) as indexof_cursor
,object_definition(referenced_id) as [referenced_object_definition]
FROM sys.dm_sql_referenced_entities(#procname, 'OBJECT')
INNER JOIN sys.objects as o on o.object_id=OBJECT_ID(referenced_entity_name)
WHERE o.type IN ('P','FN','IF','TF')
UNION ALL
SELECT referenced_database_name AS [DB],referenced_entity_name AS [OBJ],
cast(space(([lvl]+1)*2) + referenced_entity_name as varchar(max)) AS [INDENTED_OBJ],
referenced_schema_name AS [SCH],[lvl]+1 as [lvl]
,charindex('cursor',object_definition(referenced_id)) as indexof_cursor
,object_definition(referenced_id) as [referenced_object_definition]
FROM CTE as c CROSS APPLY
sys.dm_sql_referenced_entities(c.SCH+'.'+c.OBJ, 'OBJECT') as ref
INNER JOIN sys.objects as o on o.object_id=OBJECT_ID(referenced_entity_name)
WHERE o.type IN ('P','FN','IF','TF') and ref.referenced_entity_name NOT IN (c.OBJ) -- Exit Condition
)
SELECT
*
FROM CTE
EDIT: I am marking this as "solved" even though I think some improvements could be made to the below solution - I think it is "good enough" for most scenarios, but I think a fully recursive solution that can traverse an "infinitely" deep call chain is possible.
Maybe there is a more efficient way, but you could search the procedure code. It's not foolproof though in that it could get some false positives, but you shouldn't miss any. It doesn't ignore comments and variable names so it's quite possible to pick up some extra stuff.
SELECT name, xtype, colid, text
into #CodeBlocks
FROM dbo.sysobjects left join .dbo.syscomments
ON dbo.sysobjects.id = .dbo.syscomments.id
where xtype = 'P'
order by 1
SELECT name,
(SELECT convert(varchar(max),text)
FROM #CodeBlocks t2
WHERE t1.name = t2.name
ORDER BY t2.colid
FOR XML PATH('')
) text
into #AllCode
FROM #CodeBlocks t1
GROUP BY name
select #AllCode.name,
case when InterProc.name is not null then
'Possible Inter-Proc Nesting'
when #AllCode.text like '%CURSOR%FOR%CURSOR%FOR%DEALLOCATE%DEALLOCATE%' then
'Possible Nested Cursor'
when #AllCode.text like '%CURSOR%FOR%CURSOR%FOR%' then
'Possible Multiple Cursor Used'
ELSE
'Possible Cursor Used'
end
from #AllCode
left join #AllCode InterProc
on InterProc.text like '%CURSOR%FOR%'
and #AllCode.text like '%CURSOR%FOR%' + InterProc.name + '%DEALLOCATE%'
where #AllCode.text like '%CURSOR%FOR%'
I found a few nested cursors on our server I didn't know about. Interesting. :)
I'm struggling with figuring out how to join a table in Peewee based on a fairly common table postgis pattern. I need to join a table based on a postgis function (st_contains). I imagine it would look something like:
Station.select().join(Location, on=fn.ST_Intersects(Station.geom, Location.geom)).where(Location.name == 'Ravenswood')
The above query, if supported, would return all Stations in the Location named Ravenswood. The equivalent SQL would be:
SELECT station.name, station.district, station.line
FROM station INNER JOIN location ON ST_Intersects(station.geom, loc.geom)
WHERE location.name = 'Ravenswood';
Unfortunately my experiments all seem to end with this abbreviated traceback:
File "/Users/j.../python2.7/site-packages/peewee.py", line 1555, in generate_joins
left_field = field.to_field
AttributeError: 'NoneType' object has no attribute 'to_field'
Does peewee support this? I can't find it in the documentation.
Peewee's join generation checked for expressions but not function calls. I have fixed this bug in 61034c5 (released in v2.6.1). If you use peewee master you should be able to run the query now.
I have an SQL statement
SELECT dbo.sem_computer.COMPUTER_NAME,dbo.sem_computer.COMPUTER_ID,
[IP_ADDR1_TEXT],dbo.sem_computer.COMPUTER_DOMAIN_NAME, [ID],dbo.SEM_AGENT.AGENT_VERSION
FROM sem_computer, [dbo].[V_SEM_COMPUTER], IDENTITY_MAP, SEM_CLIENT,dbo.SEM_AGENT
WHERE [dbo].[V_SEM_COMPUTER].COMPUTER_ID = SEM_COMPUTER.COMPUTER_ID and dbo.IDENTITY_MAP.ID = dbo.SEM_CLIENT.GROUP_ID
and dbo.SEM_COMPUTER.COMPUTER_ID = dbo.SEM_CLIENT.COMPUTER_ID
AND dbo.SEM_COMPUTER.COMPUTER_ID = dbo.SEM_AGENT.COMPUTER_ID
AND NAME = 'My Company\Default Group'
OR NAME = 'My Company\Bronx'
order by [IP_ADDR1_TEXT]
That executed indefinitely and even freezes the SQL server when I tried to copy and paste this code.
If I remove the
OR NAME = 'My Company\Bronx'
then the the SQL statement executes just fine
We are using SQL Server 2008
Thank you
I think this whole problem becomes a lot clearer if you write ANSI-Compliant T-SQL. So rather than have your able join conditions in the WHERE clause, you have something like:
SELECT
dbo.sem_computer.COMPUTER_NAME
, dbo.sem_computer.COMPUTER_ID
, [IP_ADDR1_TEXT]
, dbo.sem_computer.COMPUTER_DOMAIN_NAME
, [ID]
, dbo.SEM_AGENT.AGENT_VERSION
FROM
sem_computer AS COM
INNER JOIN
[dbo].[V_SEM_COMPUTER] AS V
ON
COM.COMPUTER_ID = V.COMPUTER_ID
INNER JOIN
dbo.SEM_CLIENT AS CLI
ON
COM.COMPUTER_ID = CLI.COMPUTER_ID
INNER JOIN
dbo.SEM_AGENT AS AGT
ON
COM.COMPUTER_ID = AGT.COMPUTER_ID
INNER JOIN
IDENTITY_MAP AS IM
ON
CLI.GROUP_ID = IM.ID
...
Then your WHERE clause does what it is designed to do, which is filter your data. This becomes, as suggested earlier
WHERE
NAME IN('My Company\Default Group','My Company\Bronx')
The performance problem you had was, as pointed out, you were getting a cross join of all tables. But I think you would have noticed this if you write your joins in an ANSI compliant way.
I hope that helps.
Ash
OR NAME IN('My Company\Default Group','My Company\Bronx')
Should work.
When you have the AND NAME = 'My Company\Default Group'
OR NAME = 'My Company\Bronx' not in parentheses or using an IN clause, it means that it will get everything where the OR condition is satisfied, ignoring all of the other conditions.
Is it possible to put comments into Hibernate Query Language? If so, how?
Make sure your session is configured with:
<property name="hibernate.use_sql_comments">true</property>
Then do:
Query query = ...;
query.setComment("Some comment here");
and you will see something like the following in your MySQL log file (if you're using MySQL):
5998 Query /* Some comment here */ select .....
AFAIK, HQL does not support comments.
If it helps your development, Hibernate Tools (Eclipse) supports double hyphens as single-line comments in their HQL editor. Helps me a lot. I've just tried the JPQL statement
SELECT pro --ro.id, cl.name, te.ordinalNbr, tt.code, se.startYear, pro.id, pcl.name, pte.ordinalNbr, ptt.code, pse.startYear
FROM Roster ro
JOIN ro.season se
JOIN ro.team te
JOIN te.club cl
JOIN te.teamType tt
JOIN te.rosters pro
JOIN pro.season pse
JOIN pro.team pte
JOIN pte.club pcl
JOIN pte.teamType ptt
WHERE ro.id = 32
ORDER BY pse.startYear
and it returned the pro instances.
Also not quite to the point, but it might be useful nontheless.