SQL Query - MS SCCM - sql

I´m trying to make a report in MS SCCM where I can check the distribution status of Software XY. Now there can be more parts of one software installed (for example XYa, XYb....) but I only want to list the pc once in my report.
I tried this adding the keyword distinct but nothing changes. Can you help me?
Here´s my query:
select distinct SMS_R_System.Name0,__System_ADD_REMOVE_PROGRAMS0.DisplayName00,__System_ADD_REMOVE_PROGRAMS0.Version00 from vSMS_R_System AS SMS_R_System INNER JOIN Add_Remove_Programs_DATA AS __System_ADD_REMOVE_PROGRAMS0 ON __System_ADD_REMOVE_PROGRAMS0.MachineID = SMS_R_System.ItemKey INNER JOIN _RES_COLL_SMS00001 AS SMS_CM_RES_COLL_SMS00001 ON SMS_CM_RES_COLL_SMS00001.MachineID = SMS_R_System.ItemKey where __System_ADD_REMOVE_PROGRAMS0.DisplayName00 like N'%XY%'

You'll get a row returned for each different application name and version because you're including DisplayName00 and Version00 in your SELECT statement. If you just have the system name in the SELECT then the distinct will work as intended.

Related

MS Access 2016 Error: "Multi-level group by not allowed"

i'm stuck at another point in my little Access 2016 Database. My code looks like the following and i know it probably isn't the cleanest solution but i'm kinda new to this and i tried to educate myself and get some help here already.
I'm trying to play around with the reports now a little bit and i am using this test query which returns all entries of two tables joined together.
As far as i could find out I have this one subquery included that returns the prvious day inventory for each record and that is most likely the cause of my error. I found a possible solution with adding SELECT * FROM at the beginning of my code but i get a Syntax error when i do that and i'm not sure how to solve this problem.
here's my code
SELECT Stations.StationName, Product.ProductName, GasInventoryTransactions.TransactionDate, (SELECT TOP 1 Dupe.ActualInventory FROM GasInventory AS Dupe WHERE Dupe.StationID = Stations.StationID AND Dupe.ProductID = Product.ProductID AND Dupe.InventoryDate < GasInventory.InventoryDate ORDER BY Dupe.InventoryDate DESC) AS PreviousDayInventory, GasInventory.ActualInventory, GasInventoryTransactions.GasSales, GasInventoryTransactions.GasDelivery, [PreviousDayInventory]+[GasDelivery]-[GasSales] AS BookBalance, GasInventory.ActualInventory, [ActualInventory]-[BookBalance] AS OverShort
FROM (Stations INNER JOIN (Product INNER JOIN GasInventory ON Product.[ProductID] = GasInventory.[ProductID]) ON Stations.[StationID] = GasInventory.[StationID]) INNER JOIN GasInventoryTransactions ON GasInventory.[InventoryDate] = GasInventoryTransactions.[TransactionDate];
thanks for your help!

How to get a query definition from Cognos?

Is it possible to view the SQL used in Cognos's queries?
e.g. To get the XML definition of a report you can use the below SQL (copied from https://stackoverflow.com/a/24335760/361842):
SELECT CMOBJNAMES.NAME AS ObjName
, CMOBJECTS.PCMID
, CMCLASSES.NAME AS ClassName
, cast(CMOBJPROPS7.spec as xml) ReportDefinition
FROM CMOBJECTS
INNER JOIN CMOBJNAMES ON CMOBJECTS.CMID = CMOBJNAMES.CMID
INNER JOIN CMCLASSES ON CMOBJECTS.CLASSID = CMCLASSES.CLASSID
LEFT OUTER JOIN CMOBJPROPS7 ON CMOBJECTS.CMID = CMOBJPROPS7.CMID
WHERE CMOBJECTS.CLASSID IN (10, 37)
ORDER BY CMOBJECTS.PCMID;
... and from that XML you can often find sqltext elements giving the underlying SQL. However, where existing queries are being used it's hard to see where that data's coming from.
I'd like the equivalent of the above SQL to find Query definitions; though so far have been unable to find any such column.
Failing that, is there a way to find this definition through the UI? I looked under Query Studio and found the query's lineage which gives some information about the query columns, but doesn't make the data's source clear.
NB: By query I'm referring to those such as R5BZDDAN_GRAPH in the below screenshot from Query Studio:
... which would be referred to in a Cognos report in a way such as:
<query name="Q_DEMO">
<source>
<model/>
</source>
<selection autoSummary="false">
<dataItem aggregate="none" name="REG_REG" rollupAggregate="none">
<expression>[AdvRepData].[Q_R5BZDDAN_GRAPH].[REG_REG]</expression>
</dataItem>
<dataItem aggregate="none" name="REG_ORG" rollupAggregate="none">
<expression>[AdvRepData].[Q_R5BZDDAN_GRAPH].[REG_ORG]</expression>
</dataItem>
<!-- ... -->
UPDATE
For the benefit of others, here's an amended version of the above code for pulling back report definitons:
;with recurse
as (
select Objects.CMID Id, ObjectClasses.Name Class, ObjectNames.NAME Name
, cast('CognosObjects' as nvarchar(max)) ObjectPath
from CMOBJECTS Objects
inner join CMOBJNAMES ObjectNames
on ObjectNames.CMID = Objects.CMID
and ObjectNames.IsDefault = 1 --only get 1 result per object (could filter on language=English (LocaleId=24 / select LocaleId from CMLOCALES where Locale = 'en'))
inner join CMCLASSES ObjectClasses on ObjectClasses.CLASSID = Objects.CLASSID
where Objects.PCMID = objects.CMID --cleaner than selecting on root since not language sensitive
--where ObjectClasses.NAME = 'root'
union all
select Objects.CMID Id, ObjectClasses.Name Class, ObjectNames.NAME Name
, r.ObjectPath + '\' + ObjectNames.NAME ObjectPath --I use a backslash rather than forward slash as using this to build a windows path
from recurse r
inner join CMOBJECTS Objects
on objects.PCMID = r.Id
and Objects.PCMID != objects.CMID --prevent ouroboros
inner join CMOBJNAMES ObjectNames
on ObjectNames.CMID = Objects.CMID
and ObjectNames.IsDefault = 1 --only get 1 result per object (could filter on language=English (LocaleId=24 / select LocaleId from CMLOCALES where Locale = 'en'))
inner join CMCLASSES ObjectClasses
on ObjectClasses.CLASSID = Objects.CLASSID
)
select *
from recurse
where Class in ('report','query')
order by ObjectPath
Terminology:
Query Subject can be considered a table
Query Item can be considered a column
For your example the SQL might be defined in the R5BZDDAN_GRAPH query subject which is in turn defined in the Framework Manager model. The framework manager model is defined in a .cpf file which isn't in the content store at all. (it is an XML file though). This file is 'published' to Cognos to make packages.
There is also a cached version of the framework manager file on the actual cognos server (a .cqe file) although it is generally not recommended to rely on this
I say your SQL might be defined. If the query subject is a SQL query subject then that is where it is defined. If If the query subject is a model query subject then it is just a list of query items from other query subjects. These might be from many other query subjects which then have joins defined in Framework Manager. So there is no actual SQL defined there - it gets generated at run time
I'm not sure of your end requirement but there are three other ways to get SQL:
In Report Studio you can 'show generated SQL' on each query
In Framework Manager you can select one or more query subjects and show generated SQL
You can use a monitoring tool on your database to see what SQL is being submitted
If you just want to know how numbers are generated in your report, the most direct solution is to monitor your database.
Lastly keep in mind that in some rare cases, SQL defined in Framework Manager might be altered by the way the report is written

Erroneous Access 2013 error

Since a few days I'm working with Access 2013 after some years with earlier versions and there seem to have been made some changes to the internal SQL-engine. I'm working on a join query as follows:
SELECT T.STUKLIJSTNUMMER, SR.STUKLIJSTNUMMER, SR.SUB_STUKLIJSTNR
FROM STUKREG AS SR
INNER JOIN (SELECT * FROM STUKREGsubs2 WHERE SUB_STUKLIJSTNR<>'') AS T ON
SR.STUKLIJSTNUMMER=T.SUB_STUKLIJSTNR;
STUKREG is a self-referencing table. The STUKREGsubs2 query looks as follows (which works as expected):
SELECT S.STUKLIJSTNUMMER, SR.STUKLIJSTNUMMER, SR.SUB_STUKLIJSTNR
FROM STUKREG AS SR INNER JOIN STUKREGsubs1 AS S ON
SR.STUKLIJSTNUMMER=S.SUB_STUKLIJSTNR;
Of which STUKREGsubs1 is a query (which works as expected):
SELECT SR.STUKLIJSTNUMMER, SR.SUB_STUKLIJSTNR, VAL(SR.STUKLIJSTNUMMER) AS SORDER
FROM STUKREG AS SR
WHERE ABS='Sub' AND CSTR(VAL(SR.STUKLIJSTNUMMER))=SR.STUKLIJSTNUMMER
ORDER BY SR.STUKLIJSTNUMMER;
The query has always worked (in earlier versions) according to my knowledge, but now Access complains: 'The specified field 'STUKLIJSTNUMMER' could refer to more than one table listed in the FROM clause of your SQL statement'. I know what this means but I don't understand why the error occurs, because I'm clearly distinguishing between the source tables/queries. Is it because of the usage of another query in the join part? Any help is appreciated!
Make sure to alias columns with the same name from different tables, so that their names in the resulting query, are unique.
So for your STUKREGsubs2 query, add an alias to one of the STUKLIJSTNUMMER-outputs, like this:
SELECT S.STUKLIJSTNUMMER, SR.STUKLIJSTNUMMER AS STUKLIJSTNUMMER_2, SR.SUB_STUKLIJSTNR
FROM STUKREG AS SR INNER JOIN STUKREGsubs1 AS S ON
SR.STUKLIJSTNUMMER=S.SUB_STUKLIJSTNR
Then, make sure that T.STUKLIJSTNUMMER in your first query, refers to the correct column in STUKREGsubs2 (either STUKLIJSTNUMMER from the STUKREGsubs1-query or STUKLIJSTNUMMER_2 from the STUKREG-table).

Microsoft Office access has stop working error in sql Query

I tried to merge 3 tables it working fine till adding address column of third table. If i add address column and save or click Data Sheet view suddenly Access table stop working and restarts
This is my code i working as parameter but if i give correct column name it showing error. Help me to complete my task.
SELECT RPT_Invoice_Less.InvoiceNumber, RPT_Invoice_Less.Terms,
RPT_Invoice_Less.Invoicedate, RPT_Invoice_Less.OurQuote,
RPT_Invoice_Less.SalesPerson, RPT_Customer.CustomerName,
RPT_Customer.CustomerId, RPT_Customer.ContactPerson,
RPT_Customer.BillingAddress, RPT_Customer.DeliveryAddress,
RPT_Invoice_Less.OrderNumber, RPT_Invoice_Less.ShippingBy,
RPT_Invoice_Less.ShipReferenceNo, RPT_Invoice_Less.Notes,
RPT_Invoice_Less.Price, RPT_Invoice_Less.Discount, RPT_Invoice_Less.Shipping,
RPT_Invoice_Less.Tax, RPT_Invoice_Less.GrandTotal, RPT_OrionSystem.CompanyName,
RPT_OrionSystem.CompanyId, RPT_OrionSystem.RegistrationNumber,
RPT_OrionSystem.Address1, RPT_OrionSystem.MobileNumber,
RPT_OrionSystem.FaxNumber, RPT_OrionSystem.CompanyEmail,
RPT_OrionSystem.CompanyWebsite, RPT_OrionSystem.VatTinNumber
FROM (RPT_Invoice_Less
INNER JOIN RPT_Customer ON RPT_Invoice_Less.CustomerId=RPT_Customer.CustomerId)
INNER JOIN RPT_OrionSystem ON RPT_Invoice_Less.CompanyId=RPT_OrionSystem.CompanyId;
In the 10th line RPT_OrionSystem.Address1 is parameter if I give correct column name RPT_OrionSystem.Address MS Access stop working.
Thanks you guys finally I solved myself by removing sub-queries and join sub-queries directly to this query. This code I used
SELECT RPT_Invoice_Less.InvoiceNumber, RPT_Invoice_Less.Terms, RPT_Invoice_Less.Invoicedate, RPT_Invoice_Less.OurQuote, RPT_Invoice_Less.SalesPerson,
RPT_Customer.CustomerName, RPT_Customer.CustomerId, RPT_Customer.ContactPerson, RPT_Customer_Address.BillingAddress, RPT_Customer_Address.DeliveryAddress,
RPT_Invoice_Less.OrderNumber, RPT_Invoice_Less.ShippingBy, RPT_Invoice_Less.ShipReferenceNo, RPT_Invoice_Less.Notes, RPT_Invoice_Less.Price, RPT_Invoice_Less.Discount, RPT_Invoice_Less.Shipping, RPT_Invoice_Less.Tax, RPT_Invoice_Less.GrandTotal,
RPT_Company.CompanyName, RPT_Company.CompanyId, RPT_Company.RegistrationNumber, RPT_Company_Address.Address, RPT_Company.MobileNumber, RPT_Company.FaxNumber, RPT_Company.CompanyEmail, RPT_Company.CompanyWebsite, RPT_Company.VatTinNumber
FROM (((RPT_Invoice_Less
INNER JOIN RPT_Customer
ON RPT_Invoice_Less.CustomerId=RPT_Customer.CustomerId)
INNER JOIN RPT_Company
ON RPT_Invoice_Less.CompanyId=RPT_Company.CompanyId)
INNER JOIN RPT_Company_Address
ON RPT_Invoice_Less.CompanyId=RPT_Company_Address.AddressId)
INNER JOIN RPT_Customer_Address
ON RPT_Invoice_Less.CustomerId=RPT_Customer_Address.CustomerId;

Way to combine filtered results using LIKE

I have a many to many relationship between people and some electronic codes. The table with the codes has the code itself, and a text description of the code. A typical result set from a query might be (there are many codes that contain "broken" so I feel like it's better to search the text description rather than add a bunch of ORs for every code.)
id# text of code
1234 broken laptop
1234 broken mouse
Currently the best way for me to get a result set like this is to use the LIKE%broken% filter. Without changing the text description, is there any way I can return only one instance of a code with broken? So in the example above the query would only return 1234 and broken mouse OR broken laptop. In this scenario it doesn't matter which is returned, all I'm looking for is the presence of "broken" in any of the text descriptions of that person's codes.
My solution at the moment is to create a view that would return
`id# text of code
1234 broken laptop
1234 broken mouse`
and using SELECT DISTINCT ID# while querying the view to get only one instance of each.
EDIT ACTUALLY QUERY
SELECT tblVisits.kha_id, tblICD.descrip, min(tblICD.Descrip) as expr1
FROM tblVisits inner join
icd_jxn on tblVisits.kha_id = icd_jxn.kha)id inner join tblICD.icd_fk=tblICD.ICD_ID
group by tblVisits.kha_id, tblicd.descrip
having (tblICD.descrip like n'%broken%')
You could use the below query to SELECT the MIN code. This will ensure only text per id.
SELECT t.id, MIN(t.textofcode) as textofcode
FROM table t
WHERE t.textofcode LIKE '%broken%'
GROUP BY t.id
Updated Actual Query:
SELECT tblVisits.kha_id,
MIN(tblICD.Descrip)
FROM tblVisits
INNER JOIN icd_jxn ON tblVisits.kha_id = icd_jxn.kha)id
INNER JOIN tblicd ON icd_jxn.icd_fk = tbl.icd_id
WHERE tblICD.descrip like n'%broken%'
GROUP BY tblVisits.kha_id