Help with Delphi 7, ADO, & MS Access SQL Statement - sql

I have three tables (in a MS Access Database 2000 file *.mdb)
Knowledge
id
question
answer
Knowledge_Keywords
id
knowledgeid
keywordsid
Keywords
id
keyword
Need to get all the keywords for a knowledge
Select distinct keyword from keywords KW
Join knowledge_keywords KKW on KKW.keywordid = KW.id
Join Knowledge K on K.id = KKW.knowledgeid
Where k.id = 10
of course 10 is a example, i actually use a parameter there
Where k.id = :AKnowId';
and fill it in in code
qry.Parameters.ParamByName('AKnowId').Value:= AKnowledgeId;
anyway, i think the SQL is qrong, any help would be greatly appreciated

Get the SQL working properly within Access itself (make a query, try your SQL, see if it returns anything). THEN worry about Delphi.

Solved it!
Select distinct keyword
from (keywords KW
inner Join knowledge_keywords KKW on KKW.keywordid = KW.id)
inner Join Knowledge K on K.id = KKW.knowledgeid
Where k.id = 10

Related

SQL query does not show the correct kilos, I don't know where is the problem

This is my SQL query in text format:
SELECT sum(D.Kilogramos) as Kilogramos, C.Categoria , C.Tipo S Tipo, LA.Huerta,TC.TipoCorte, LA.JefeAcopio,LA.IdLote
FROM dbo.MOV_EmpaqueDetalle D
INNER JOIN dbo.Rep_Lote LA on LA.IdLote= D.IdLote
INNER JOIN dbo.MOV_OrdenesCorte MO on MO.IdOrdenCorte = LA.IdOrdenCorte
INNER JOIN dbo.PRO_Productos P on P.IdProducto=D.IdProducto
INNER JOIN dbo.PRO_Categorias C ON C.IdCategoria=P.IdCategoria
INNER JOIN dbo.MOV_Acuerdos A on A.IdAcuerdo=LA.IdAcuerdo
INNER JOIN dbo.MOV_TiposCorte TC on A.IdTipoCorte=TC.IdTipoCorte
WHERE CAST(MO.Fecha AS DATE) BETWEEN '2018-10-23' AND '2018-10-23'
GROUP BY LA.Huerta, LA.IdLote,C.Categoria, C.Tipo, TC.TipoCorte, LA.JefeAcopio,Mo.Fecha
ORDER BY LA.Huerta
The rows in the column kilogramos of the Huerta EL DOS are wrong, the information correct must be the following:
Kilogramos Huerta
13807.00 El DOS
I have got the accumulated row in sum function, the kilograms are wrong.
Its kind of hard to provide an answer with the few information you provided, but I would suggest to check whether your GROUP BY is correct.
If you really just need the sum Kilogramos over the different Huertas your group condition should look like this: GROUP BY LA.Huerta

MS Access INNER JOIN/LEFT JOIN problems

I have the following SQL string which tries to combine an INNER JOIN with a LEFT JOIN in the FROM section.
As you can see I use table VIP_APP_VIP_SCENARIO_DETAIL_LE to perform the query. When I use it against this table, Access give me an "Invalid Operation" error.
Interestingly, when I use the EXACT same query using the VIP_APP_VIP_SCENARIO_DETAIL_BUDGET or VIP_APP_VIP_SCENARIO_DETAIL_ACTUALS table, it performs flawlessly.
So why would it work on two tables but not the other? All fields are in all tables and the data types are correct.
As a side note: on the query with the error, if I change the LEFT JOIN to an INNER JOIN, it runs with no problem! I really need a LEFT JOIN though.
SELECT
D.MATERIAL_NUMBER,
D.MATERIAL_DESCRIPTION,
D.PRODUCTION_LOT_SIZE,
D.STANDARDS_NAME,
D.WORK_CENTER,
S.OP_SHORT_TEXT,
S.OPERATION_CODE,
D.LINE_SPEED_UPM,
D.PERCENT_STD,
D.EQUIPMENT_SU,
D.EQUIPMENT_CU,
D.OPERATOR_NUM,
V.COSTING_LOT_SIZE,
V.VOL_TOTAL_ADJ
FROM
([STDS_SCENARIO: TEST] AS D INNER JOIN MASTER_SUMMARY AS S ON
D.MATERIAL_NUMBER = S.MATERIAL_NUMBER AND D.WORK_CENTER = S.WORK_CENTER)
LEFT JOIN
(SELECT ITEM_CODE, COSTING_LOT_SIZE, VOL_TOTAL_ADJ
FROM
VIP_APP_VIP_SCENARIO_DETAIL_LE
WHERE SCENARIO_ID = 16968) AS V ON D.MATERIAL_NUMBER = V.ITEM_CODE
ORDER BY D.MATERIAL_NUMBER, D.STANDARDS_NAME, S.OPERATION_CODE;
tried to mock this up in SQL server with some tables of my own, but the structure seemed to work, this follows the pattern referenced above. (hopefully no syntax errors left here)
SELECT * FROM (
select
D.MATERIAL_NUMBER,
D.MATERIAL_DESCRIPTION,
D.PRODUCTION_LOT_SIZE,
D.STANDARDS_NAME,
D.WORK_CENTER,
S.OP_SHORT_TEXT,
S.OPERATION_CODE,
D.LINE_SPEED_UPM,
D.PERCENT_STD,
D.EQUIPMENT_SU,
D.EQUIPMENT_CU,
D.OPERATOR_NUM
FROM [STDS_SCENARIO: TEST] D
INNER JOIN MASTER_SUMMARY S
ON D.MATERIAL_NUMBER = S.MATERIAL_NUMBER AND D.WORK_CENTER = S.WORK_CENTER) AS J
LEFT JOIN
(SELECT ITEM_CODE, COSTING_LOT_SIZE, VOL_TOTAL_ADJ
FROM
VIP_APP_VIP_SCENARIO_DETAIL_LE
WHERE SCENARIO_ID = 16968) AS V ON J.MATERIAL_NUMBER = V.ITEM_CODE
ORDER BY J.MATERIAL_NUMBER, J.STANDARDS_NAME, J.OPERATION_CODE;
Had help from a friend and we discovered that it was a casting problem between a linked Oracle table and the Access table. To fix the problem we casted both sides of the linked fields to a string:
CSTR(D.[MATERIAL_NUMBER]) = CSTR(V.[ITEM_CODE])

Translating query from Firebird to PostgreSQL # 2

I have a SQL query :
SELECT TRIM(RL.RDB$RELATION_NAME), TRIM(FR.RDB$FIELD_NAME), FS.RDB$FIELD_TYPE, TRIM(RC.RDB$CONSTRAINT_TYPE)
FROM RDB$RELATIONS RL
LEFT OUTER JOIN RDB$RELATION_FIELDS FR ON FR.RDB$RELATION_NAME = RL.RDB$RELATION_NAME
LEFT OUTER JOIN RDB$FIELDS FS ON FS.RDB$FIELD_NAME = FR.RDB$FIELD_SOURCE
LEFT OUTER JOIN RDB$INDEX_SEGMENTS ISS ON ISS.RDB$FIELD_NAME = FR.RDB$FIELD_NAME
INNER JOIN RDB$RELATION_CONSTRAINTS RC ON RC.RDB$CONSTRAINT_NAME = ISS.RDB$INDEX_NAME
WHERE (RL.RDB$VIEW_BLR IS NULL)
ORDER BY RL.RDB$RELATION_NAME, FR.RDB$FIELD_NAME
Yesterday i asked how correctly translate a query from Firebird to PostgreSQL and I'm asking once again :) . (But I'd just started working with databases and got really hard task (rewrite a big part of code, because RDBMS had been changed) ). A big part is done, but I have a problems with this translation. So, can u help me? There is some code which i've translated by myself.

Help with Delphi 7, ADO, & MS Access SQL Statement - Part Deuce

I need help understanding why my SQL does not work. Or, if i need to write it differently to get the results i need. As the title suggests, I am using Delphi 7, with ADO components, and a MS Access 2000 database. You can see my table structure from Part I here:
Help with Delphi 7, ADO, & MS Access SQL Statement
The SQL i am currently using to get all knowledge based on keywords is as follows:
select * from (knowledge K
inner join knowledge_keywords KKW on KKW.knowledgeid = K.id)
inner join keywords KW on KW.id = KKW.keywordid
where (KW.keyword = 'job') AND (KW.keyword = 'task')
However, this does not return and results, when there is clearly both of those words in the knowledge_keywords table with the same knowledge id.
However, if i do the same SQL with an OR instead of an AND, i get the two records i expected
select * from (knowledge K
inner join knowledge_keywords KKW on KKW.knowledgeid = K.id)
inner join keywords KW on KW.id = KKW.keywordid
where (KW.keyword = 'job') AND (KW.keyword = 'task')
thanks for any help
Think about it this way: How many records are there in knowledge_keywords for which it is true both that keyword = 'job' AND keyword = 'task'. There are no such records. When you use AND you're asking for records that satisfy both the first condition AND the second condition at the same time. When you use OR, you're asking for records that satisfy one condition OR the other one (or both).
In this case, OR expresses what you want. AND expresses something different.
You can also use KW.keyword IN ('job', 'task') which is more concise and, perhaps, clearer.
I think the first query won't return any result, does it? That's because 'and' in speech differs from 'and' in programming. When you say, you want the keywords 'job' and 'task', you actually mean you want the rows where keyword is either 'job' or 'task'. A keyword cannot be both 'job' and 'task' so that query won't return any rows. You could replace the OR with an IN in the form of
WHERE KW.Keyword in ('job', 'task')
But this probably won't give you the result you want. I suspect you need to find articles that match both keywords.
To check if a knowledgebase has both keywords, you might need something like this (although I'm not sure if Access accepts this:
select
*
from
knowledge K
where
exists
(select 'x' from
knowledge_keywords KKW
inner join keywords KW on KW.id = KKW.keywordid
where
KKW.knowledgeid = K.id and
KW.keyword = 'job')
and exists
(select 'x' from
knowledge_keywords KKW
inner join keywords KW on KW.id = KKW.keywordid
where
KKW.knowledgeid = K.id and
KW.keyboard = 'task') and
[edit]
A different approach, that might work better in Access (I'm sorry I can't test it) is by using a count like this. I made a small assumption about the fields in K for this example.
This way, you join each keyword in the list. For a knowledge base article that has both 'job' and 'task' it will return two rows at first. These rows are then grouped on the Knowledge fields, and the rows are counted. Only the articles where count matches the total number of keywords are returned.
Possible problem: When an article has the same keyword (job) linked twice, it is still returned. This can be solved by preventing that from happening using unique constraints.
select
K.ID,
K.Title,
K.Content
from
knowledge K
inner join knowledge_keywords KKW on KKW.knowledgeid = K.id)
inner join keywords KW on KW.id = KKW.keywordid
where
KW.keyword in ('job', 'task')
group by
K.ID,
K.Title,
K.Content
having
count(*) = 2 /* Number of keywords */

Sorting rows by count of a many-to-many associated record

I know there are a lot of other SO entries that seem like this one, but I haven't found one that actually answers my question so hopefully one of you can either answer it or point me to another SO question that is related.
Basically, I have the following query that returns Venues that have any CheckIns that contain the searched Keyword ("foobar" in this example).
SELECT DISTINCT v.*
FROM "venues" v
INNER JOIN "check_ins" c ON c."venue_id" = v."id"
INNER JOIN "keywordings" ks ON ks."check_in_id" = c."id"
INNER JOIN "keywords" k ON ks."keyword_id" = k."id"
WHERE (k."name" = 'foobar')
I want to SELECT and ORDER BY the count of the matched Keyword for each given Venue. E.g. if there have been 5 CheckIns that have been created, associated with that Keyword, then there should be a returned column (called something like keyword_count) with the value 5 which is sorted.
Ideally this should be done without any queries in the SELECT clause, or preferably none at all.
I've been struggling with this for a while and my mind is just going blank (perhaps it's been too long a day) so some help would be greatly appreciated here.
Thanks in advance!
Sounds like you need something like:
SELECT v.x, v.y, count(*) AS keyword_count
FROM "venues" v
INNER JOIN "check_ins" c ON c."venue_id" = v."id"
INNER JOIN "keywordings" ks ON ks."check_in_id" = c."id"
INNER JOIN "keywords" k ON ks."keyword_id" = k."id"
WHERE (k."name" = 'foobar')
GROUP BY v.x, v.y
ORDER BY 3