KQL - Joining 2 tables sing Equality by Value - kql

I am attempting to join two tables in KQL within Microsoft Defender.
These tables don't have matching columns however they do have matching fields.
LeftTable: EmailEvents Field: RecipientEmailAddress
RightTable: IdentityInfo Field: AccountUpn
The query I am using is as follows
EmailEvents
| where EmailDirection == "Inbound"
| where Subject == "invoice" or SenderFromAddress == "testtest#outlook.com"
| project RecipientEmailAddress, Subject, InternetMessageId, SenderFromAddress
| join kind=inner (IdentityInfo
| distinct AccountUpn, AccountDisplayName, JobTitle , Department, City, Country)
on $left.RecipientEmailAddress -- $right.AccountUpn
I am seeing the error
Semantic error
Error message
join: only column entities or equality expressions are allowed in this context.
How to resolve
Fix semantic errors in your query
Can someone assist I am not sure where I am going wrong here.

try replacing this:
on $left.RecipientEmailAddress -- $right.AccountUpn
with this:
on $left.RecipientEmailAddress == $right.AccountUpn

Related

Grafana: join variables, retrieved from sql queries

I have 2 variables.
client.
Query:
SELECT
title AS __text,
concat('"', id::text,'"') AS __value
FROM clients
WHERE active=true
For value I use concatenation with quotation marks as some values can take string-values.
order.
Order:
select name
from orders
where concat('"',client_id::text,'"') =ANY(ARRAY[${client:csv}])
And join between 2 variables does not work - I receive the error like:
Templating [order] Error updating options: pq: column “1106102844810989568” does not exist
Without concatenation join working well, but it is not a target case.
What am I doing wrong?
The solution is following: I replaced ${client:csv} on ${client:sqlstring}
So the query for 2 variable as follows:
select name
from orders
where concat('"',client_id::text,'"') =ANY(ARRAY[${client:sqlstring}])

SQL One to many relationships, duplicate/results being returned as unique rows

I have a database and some of the tables have one to many relationships. How do I eliminate the results being returned as its own unique row?
For instance I have a initiative table and a initiative can have many funding requirements. When I perform an inner join I'm getting the results but it looks like the rows are duplicating to output a unique value from the funding table.
From the results, it should be like this
Row 3,4,5 should be in one row listing the results with the the funding required
Description | Acad_priority_1 | Acad_priority_2 | beginning_fiscal_year |
Develop... | false | true | 2018/2019 |
| 2018/2019 |
| 2019/2020
Can you please steer me in the right direction or show me how the SQL should be structured to achieve this?
SQL:
SELECT plan_master.plan_id,
plan_master.date_submitted,
plan_master.filename,
initiative_master.plan_id,
initiative_master.NAME,
initiative_master.acad_priority_1,
funding.initiative_id,
funding.beginning_fiscal_year
FROM plan_master
JOIN initiative_master
ON plan_master.plan_id = initiative_master.plan_id
JOIN funding
ON initiative_master.initiative_id = funding.initiative_id
ORDER BY Filename
|plan_id|date_submitted|filename|plan_id|NAME|acad_priority_1|initiative_id|begginning_fiscal_year|
|16F44FFE-5434-4E52-9D9A-F45C0A49D8E2|2018-12-03|1.txt|16F44FFE-5434-4E52-9D9A-F45C0A49D8E2|Space Utilization framework|false|8CCE0311-0E3C-467D-B675-04817A473056|2018/2019
|16F44FFE-5434-4E52-9D9A-F45C0A49D8E2|2018-12-03|1.txt|16F44FFE-5434-4E52-9D9A-F45C0A49D8E2|Space Utilization framework|false|8CCE0311-0E3C-467D-B675-04817A473056|2019/2020
|16F44FFE-5434-4E52-9D9A-F45C0A49D8E2|2018-12-03|1.txt|16F44FFE-5434-4E52-9D9A-F45C0A49D8E2|Space Utilization framework|false|8CCE0311-0E3C-467D-B675-04817A473056|2020/2021
The 2 beginning fiscal year values cannot be combined into a single row unless you want to concatenate them with commas (or another separator), or write a function to show the value as a range, for example 2018-2020. You can however get rid of the 4th record using distinct or using the below mentioned over/partition by clauses.
If you don't mind, can you run the following query and provide the results that will help me identify the duplication issue:
SELECT plan_master.plan_id,
plan_master.date_submitted,
plan_master.filename,
plan_master.department,
plan_master.last_name,
plan_master.first_name,
plan_master.email,
plan_master.mission_statement,
plan_master.vision_statement,
plan_master.goals_objectives,
initiative_master.plan_id,
initiative_master.NAME,
initiative_master.description,
initiative_master.acad_priority_1,
initiative_master.acad_priority_2,
initiative_master.acad_priority_3,
initiative_master.acad_priority_4,
initiative_master.acad_priority_5,
initiative_master.acad_priority_6,
initiative_master.operational_sustainability,
initiative_master.people_plan,
funding.initiative_id,
funding.beginning_fiscal_year
FROM plan_master
JOIN initiative_master
ON plan_master.plan_id = initiative_master.plan_id
JOIN funding
ON initiative_master.initiative_id = funding.initiative_id
ORDER BY Filename
Once you get to the cause, you can either use a better join clause (multiple conditions), add a where clause, or use the OVER clause in conjunction with the PARTITION BY clause to filter the data based on a ROW_NUMBER().
A simple join returns a cartesion product. If one table has 2 rows and another has 3, then there will be 6 rows of data. Need to do distinct on the data. You can do this:
SELECT plan.date_submitted,
plan.filename,
plan.department,
plan.last_name,
plan.first_name,
plan.email,
plan.mission_statement,
plan.vision_statement,
plan.goals_objectives,
initiative.Name,
initiative.description,
initiative.acad_priority_1,
initiative.acad_priority_2,
initiative.acad_priority_3,
initiative.acad_priority_4,
initiative.acad_priority_5,
initiative.acad_priority_6
FROM plan_master as plan
inner join (select distinct init.plan_id, init.NAME,
init.description,
init.acad_priority_1,
init.acad_priority_2,
init.acad_priority_3,
init.acad_priority_4,
init.acad_priority_5,
init.acad_priority_6,
init.operational_sustainability,
init.people_plan,
funding.beginning_fiscal_year from initiative_master as init
join funding on funding.initiative_id = init.initiative_id ) as initiative
ON plan.plan_id = initiative.plan_id
ORDER BY Filename

SQL query for crystal reports produces duplicate results

I created 3 tables TstInvoice, TstProd, TstPersons and added some data:
INVOICE_NBR CLIENT_NR VK_CONTACT
A10304 003145 AT
A10305 000079 EA
A10306 004458 AT
A10307 003331 JDJ
PROD_NR INVOICE_NBR
P29366 A10304
P29367 A10304
P29368 A10305
P29369 A10306
P29370 A10306
P29371 A10307
PERS_NR INITIALEN STATUS PERSOON
0001 AT 7 Alice Thompson
0002 EA 1 Edgar Allen
0003 JDJ 1 John Doe Joe
0004 AT 1 Arthur Twins
The parameter that is passed to the crystal report is the INVOICE_NBR.
On my crystal report I put some fields from the databases and one sql expression:
(
SELECT "TstPersons"."PERSOON" FROM "TstPersons"
WHERE "TstPersons"."INITIALEN" = "TstInvoice"."VK_CONTACT" AND "TstPersons"."STATUS" = 1
)
The full query that is generated:
SELECT "TstInvoice"."INVOICE_NBR", "TstInvoice"."CLIENT_NR", "TstPersons"."STATUS", "TstPersons"."PERSOON", "TstProd"."PROD_NR", "TstProd"."INVOICE_NBR", (
SELECT "TstPersons"."PERSOON" FROM "TstPersons"
WHERE "TstPersons"."INITIALEN" = "TstInvoice"."VK_CONTACT" AND "TstPersons"."STATUS" = 1
)
FROM ("GCCTEST"."dbo"."TstInvoice" "TstInvoice" INNER JOIN "GCCTEST"."dbo"."TstProd" "TstProd" ON "TstInvoice"."INVOICE_NBR"="TstProd"."INVOICE_NBR") INNER JOIN "GCCTEST"."dbo"."TstPersons" "TstPersons" ON "TstInvoice"."VK_CONTACT"="TstPersons"."INITIALEN"
WHERE "TstInvoice"."INVOICE_NBR"='A10304'
The result is as shown in the screenshot:
As you can see the TstPersons.PERSOON field is populated with Alice Thompson and the sql expression field is correctly populated with Arthur Twins. However, I would like only to see the prod_nr once. With this query it produces the prod numbers twice because of the double entry for "AT" despite the fact that I ask for only status 1. I could just delete the old entry but I want to know if it's possible this way.
* edit * I added the status = 1 to the "record selection formula editor" and that seems to work. Not need the sql expression field at all. Not sure if this is the correct way to go though.
So now it looks like this:
SELECT "TstInvoice"."INVOICE_NBR", "TstInvoice"."CLIENT_NR", "TstPersons"."STATUS", "TstPersons"."PERSOON", "TstProd"."PROD_NR", "TstProd"."INVOICE_NBR"
FROM ("GCCTEST"."dbo"."TstInvoice" "TstInvoice" INNER JOIN "GCCTEST"."dbo"."TstProd" "TstProd" ON "TstInvoice"."INVOICE_NBR"="TstProd"."INVOICE_NBR") INNER JOIN "GCCTEST"."dbo"."TstPersons" "TstPersons" ON "TstInvoice"."VK_CONTACT"="TstPersons"."INITIALEN"
WHERE "TstInvoice"."INVOICE_NBR"='A10304' AND "TstPersons"."STATUS"=1
You have a very weak join in your query due to the duplicate values found in the INITIALEN column. Using the STATUS = 1 criteria is a work-around more than a solution because if you ever need to report on an invoice where the contact has a status other than 1, you will need to modify the report's design to allow your join to work because the STATUS value is not found on the invoice to allow a proper join to occur.
You are also running a risk of this work-around breaking down completely should you have another contact with both the same initials and status values as another.
The correct way to solve this problem would be to join TstInvoice to TstPersons through a field that has unique values. The PERS_NR column appears to be a good choice for this.
This is also going to require a redesign of the TstInvoice table to include the PERS_NR column as a Foreign Key.
A stronger join between invoices and persons would also remove the need for that sub-query in you selection statement. This would simplify your query down to the following:
SELECT "TstInvoice"."INVOICE_NBR", "TstInvoice"."CLIENT_NR", "TstPersons"."STATUS", "TstPersons"."PERSOON", "TstProd"."PROD_NR", "TstProd"."INVOICE_NBR"
FROM "GCCTEST"."dbo"."TstInvoice" "TstInvoice"
INNER JOIN "GCCTEST"."dbo"."TstProd" "TstProd"
ON "TstInvoice"."INVOICE_NBR"="TstProd"."INVOICE_NBR"
INNER JOIN "GCCTEST"."dbo"."TstPersons" "TstPersons"
ON "TstInvoice"."PERS_NR"="TstPersons"."PERS_NR"
WHERE "TstInvoice"."INVOICE_NBR"='A10304'

Joining SQL statements Atrium Syntess Firebird DB

I'm trying to get (one or multiple) number lines (PROGCODE) that are attached to an OBJECT (i.e. a building) that is connected to a Relation which in turn has a GC_ID (relation unique ID). I need all the buildings & progcodes connected to a relation ID in a firebird 2.5 database generated by my companies ERP system.
I can look through all the tables in the firebird database and run select queries on them.I like to think I have the join statement syntax down and I know how to find the unique ID belonging to a relation, unfortunately I'm unsure how I can find the correct table that houses the information I seek.
The table I think this data is in has the following fields:
GC_ID, DEVICE_GC_ID, USER_GC_ID, CODE, DESCRIPTION.
However when I query it using
select GC_ID, DEVICE_GC_ID, USER_GC_ID, CODE, DESCRIPTION
from AT_PROGCODE A
Then I get a description of the fields I'm trying to query.
i.e.
| GC_ ID : 100005 | DEVICE_GC_ID : 100174 | USER_GC_ID : 1000073 | DESCRIPTION: >description of what I'm trying to query< |
Can anyone shed some insight how I should handle this?
Update 7-09-2017
I spoke with the ERP consultant and was told the tables I needed (if anyone reading this is using syntess Atrium; the AT_BRENT table holds a description of all the tables.)
However, I've run into a new problem; the data I get from my sql query keeps streaming (it seems to never end with me stopping the script at 90 mil loops and the ERP program crashing if I ask for a count).
select A.GC_OMSCHRIJVING Bedrijf, A.GC_CODE ,M.GC_OMSCHRIJVING Werktitel,
M.TELEFOON1, M.TELEFOON2, M.MOBIEL, M.EMAIL,
M.URL, M.DOORKIES_NR, M.WERKLOCATIE, M.EMAIL_INTERN
from AT_MEDEW M , AT_RELATIE A
JOIN AT_MEDEW ON A.GC_ID = M.GC_ID
WHERE M.TELEFOON1 <> '' OR M.TELEFOON2 <> '' OR M.MOBIEL <> ''
Any ideas on what's the cause for my latest peril?
First I had to find the AT_BRENT table which holds all the descriptions for tables in Syntess Atrium
Then I was using a CROSS JOIN (as pointed out by https://stackoverflow.com/users/696808/bacon-bits )
I ended up using
select A.GC_OMSCHRIJVING Bedrijf, A.GC_CODE ,M.GC_OMSCHRIJVING Werktitel,
M.TELEFOON1, M.TELEFOON2, M.MOBIEL, M.EMAIL,
M.URL, M.DOORKIES_NR, M.WERKLOCATIE, M.EMAIL_INTERN
from AT_MEDEW M
JOIN AT_RELATIE A ON A.GC_ID = M.GC_ID
WHERE M.TELEFOON1 <> '' OR M.TELEFOON2 <> '' OR M.MOBIEL <> ''
Thank you all who helped.

How to Group_Concat with a 3-table JOIN for genealogy

I am failing to grasp how I can get the following outcome. I thought perhaps via GROUP_CONCAT, but I am also joining on 3 tables, and unclear on the correct syntax or if this is even the best approach.
Generic table layout:
Table Users: user_id | first | last
Table Orgs org_id | org_name
Table Relationship user_id | org_id | start_year | end_year
The relationship table has MANY entries, that may be associated with that specific user_id.
I need to get the User columns: id, first, last. I'd like to try and group the org data into 1 concatenated, delimited field. Maybe a double group_concatenation is needed? Which would consist of the org_id, org_name, start_year & end_year for all records in the relationship table that match the user_id. I'm hoping for an output like this:
Each '|' represents a new column/piece of data.
If there was only 1 org_id associated with the user_id, the output would be (similar) to:
user_id | first | last | org_id-org_name-start_year-end_year
If there were more than 1 org found/associated with that user_id, the output would have more concatenated/delimited data in the same column:
user_id | first | last | org_id-org_name-start_year-end_year^org_id-org_name-start_year-end_year^org_id-org_name-start_year-end_year
(Notice the '-' delimiter between values and the '^' delimiter between new 'org-grouped' data.)
When I grab that data, I can then just break it up (on the backend/PHP side of things) into an array or whatever.
I'm not sure how I can GROUP_CONCAT (if that is even the best approach here?) while I have to JOIN on 3 separate tables.
This is not my REAL query. (I'm not sure if I should post it, as I do not want to cause any confusion as it does NOT match my dummy table/column names.)
I just wanted to show my attempt that gets me 3 individual rows, (using my JOINS) but no GROUP_CONCAT stuff:
SELECT genealogy_users.imis_id, genealogy_users.full_name,
genealogy_users.member_email, genealogy_orgs.org_id,
genealogy_orgs.org_name, genealogy_relations.user_id,
genealogy_relations.relation_type, genealogy_relations.start_year,
genealogy_relations.end_year
FROM genealogy_users
INNER JOIN genealogy_relations ON genealogy_users.imis_id = genealogy_relations.user_id
INNER JOIN genealogy_orgs ON genealogy_relations.org_id = genealogy_orgs.org_id
WHERE genealogy_users.imis_id = '00003';
UPDATE:
Well I seemed to have fudged my way through it. But I'm not sure how legit this is.
Its -ALMOST- there. I believe I still need a JOIN or something? Since the genealogy_orgs.org_id = '84864' is hardcoded, and it should NOT be. Maybe it needs to come from a JOIN or something?
SELECT genealogy_users.*,
(SELECT GROUP_CONCAT(org_id,'-',
(SELECT org_name FROM genealogy_orgs WHERE genealogy_orgs.org_id = '84864'),
'-',start_year,'-',end_year,'^')
FROM genealogy_relations WHERE genealogy_relations.user_id = genealogy_users.imis_id
) AS alumni_list
FROM genealogy_users
WHERE genealogy_users.imis_id = '00003';
UPDATE 2:
My final attempt, which I think is getting me what I need. (But it's late, and I'll check back tomorrow and look at things more closely.)
SELECT genealogy_users.imis_id, genealogy_users.full_name,
genealogy_users.member_email, genealogy_orgs.org_id,
genealogy_orgs.org_name, genealogy_relations.user_id,
genealogy_relations.relation_type, genealogy_relations.start_year,
genealogy_relations.end_year,
(SELECT GROUP_CONCAT(org_id,'-',org_name,'-',start_year,'-',end_year,'^')
FROM genealogy_relations
WHERE genealogy_relations.user_id = genealogy_users.imis_id
) AS alumni_list
FROM genealogy_users
INNER JOIN genealogy_relations ON genealogy_users.imis_id = genealogy_relations.user_id
INNER JOIN genealogy_orgs ON genealogy_relations.org_id = genealogy_orgs.org_id
WHERE genealogy_users.imis_id = '00003';
Is there anything to make note of in the above attempt? Or is there a better approach? Hopefully something easily readable so it makes sense?