I have an SQLite database db and a view pending_nodes. To find pending_subnet - pending nodes whose upstream is also a pending node - I've prepared this statement:
db eval {
SELECT * FROM pending_nodes AS left
INNER JOIN pending_nodes AS right ON left.process=right.upstream} v {
parray v
# do stuff...
}
To my surprise parray gives me this result:
v(*) = node process type upstream node process type upstream
v(node) = 2
v(process) = 6
v(type) = reference
v(upstream) = 5
The printed data is as expected, but the v(*) list is duplicated. Looks weird and suspect I've done something wrong.
Q: What did I do wrong?
From #JoakimDanielson comment, selecting * from just one of tables (right) gives expected results:
SELECT right.* FROM pending_nodes AS left
INNER JOIN pending_nodes AS right ON left.process=right.upstream
Related
I have 4 tables and the following SQL query:
SELECT * FROM dbo.Synola, dbo.Stores, dbo.Fpa, dbo.Nomismata
WHERE
dbo.Stores.Store_id = dbo.Synola.Store_id
AND
dbo.Stores.fpa_id = dbo.Fpa.fpa_id
AND
dbo.Stores.nomisma_id = dbo.Nomismata.nomisma_id
The above works fine and without errors.
My problem is that when I am trying to loop the above query:
Currently, in my Stores TABLE, I have only 2 stores and I want in the loop to get results ONLY for 2 records. The 2 records with my 2 stores. But unfortunately I am receiving more than 2 records.
Which is the correct syntax of my query in a way to receive results only for my 2 stores in the loop?
This should only retrieve data that's available in ALL tables. Therefore, it there's not a match to the main Stores table, then the result wont show.
SELECT *
FROM Stores s
JOIN Synola sy ON sy.Store_id = s.Store_id
JOIN Fpa f ON f.fpa_id = s.fpa_id
JOIN Nomismata n ON n.nomisma_id = s.nomisma_id
If you are getting more rows because there are more matches in other tables, then you need to look into adding more WHERE conditions or using another type of JOIN.
More info: https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins
Edit: To see where you are getting multiple matches on your JOIN:
SELECT s.Store_id "Store_id from Store",
,sy.Store_id "Store_id from Synola"
,s.fpa_id "fpa_id from Store"
,f.fpa_id "fpa_id from Fpa"
,s.nonisma_id "nomisma_id from Store"
,n.nonisma_id "nomisma_id from Nomismata"
FROM Stores s
JOIN Synola sy ON sy.Store_id = s.Store_id
JOIN Fpa f ON f.fpa_id = s.fpa_id
JOIN Nomismata n ON n.nomisma_id = s.nomisma_id
When I execute the query below I get the following error message :
ORA-00918: column ambigously defined
ORA-02063: preceding line from ABC
Query:
SELECT
dos.*,
cmd.*,
cmd_r.*,
adr_inc.*,
adr_veh.*,
loc.*,
fou_d.*,
fou_r.*, --Works if I comment this line
mot.*
FROM
DOSSIERS#ABC dos
LEFT JOIN CMDS#ABC cmd ON cmd.DOS_CODE_ID = dos.dos_code_id
LEFT JOIN CMDS_RECCSTR#ABC cmd_r ON cmd_r.DOS_CODE_ID = dos.DOS_CODE_ID AND cmd_r.CMD_CODE_ID = cmd.CMD_CODE_ID AND cmd_r.CMD_DT_CREAT = cmd.CMD_DT_CREAT
LEFT JOIN HISTO_ADR#ABC adr_inc ON adr_inc.DOS_CODE_ID = dos.DOS_CODE_ID
LEFT JOIN HISTO_ADR#ABC adr_veh ON adr_veh.DOS_CODE_ID = dos.DOS_CODE_ID
LEFT JOIN LOC#ABC loc ON dos.DOS_CODE_ID = loc.DOS_CODE_ID
LEFT JOIN FOURNISS#ABC fou_d ON fou_d.PAY_CODE_ID = loc.PAY_CODE_ID_D AND fou_d.FOU_CODE_ID = loc.FOU_CODE_ID_D
LEFT JOIN FOURNISS#ABC fou_r ON fou_r.PAY_CODE_ID = loc.PAY_CODE_ID_R AND fou_r.FOU_CODE_ID = loc.FOU_CODE_ID_R
LEFT JOIN REF_MOT#ABC mot ON mot.RMR_CODE_ID = cmd_r.RMR_CODE_ID
WHERE
dos.REF_EXT = 'XXXXXXX'
If I comment fou_r.* in SELECT it works.
The following queries don't work neither:
SELECT *
FROM ... ;
SELECT (SELECT count(xxx) FROM ...)
FROM ...;
I looked at similar issues on SO but they were all using complex queries or was using many SELECT inside WHERE. Mine is simple that is why I don't understand what could be wrong.
Current Database: Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
Target Database (refers to db link ABC target): Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi
Client: Toad for Oracle 9.7.2.5
You seem to be hitting bug 13589271. I can't share details from MOS, but there isn't much to share anyway. It's related to the remote table having a column with a 30-character name though, as you have in your remote FOURNIUSS table.
Unfortunately simply aliasing the column in your query, like this:
fou_d.COLUMN_WITH_30_CHARACTERS_NAME alias_a,
fou_r.COLUMN_WITH_30_CHARACTERS_NAME alias_b,
... doesn't help and still gets the same error, as the alias is applied by the local database and the problem seems to be during the remote access. What does seem to work is using an in-line view to apply a column alias before the join:
...
LEFT JOIN LOC#ABC loc ON dos.DOS_CODE_ID = loc.DOS_CODE_ID
LEFT JOIN (
SELECT PAY_CODE_ID, FOU_CODE_ID, COLUMN_WITH_30_CHARACTERS_NAME alias_a FROM FOURNISS#ABC
) fou_d ON fou_d.PAY_CODE_ID = loc.PAY_CODE_ID_D AND fou_d.FOU_CODE_ID = loc.FOU_CODE_ID_D
LEFT JOIN (
SELECT PAY_CODE_ID, FOU_CODE_ID, COLUMN_WITH_30_CHARACTERS_NAME alias_b FROM FOURNISS#ABC
) fou_r ON fou_r.PAY_CODE_ID = loc.PAY_CODE_ID_R AND fou_r.FOU_CODE_ID = loc.FOU_CODE_ID_R
LEFT JOIN REF_MOT#ABC mot ON mot.RMR_CODE_ID = cmd_r.RMR_CODE_ID
...
This even works if you give the column the same alias in both inline views. The downside is that you have to explicitly list all of the columns from the table (or at least those you're interested in) in order to be able to apply the alias to the problematic one, but having done so you can still use fou_d.* and fou_r.* in the outer select list.
I don't have an 11.2.0.2 database but I've run this successfully in an 11.2.0.3 database which still showed the ORA-00918 error from your original code. It's possible something else in 11.2.0.2 will stop this workaround being effective, of course. I don't see the original problem in 11.2.0.4 at all, so upgrading to that terminal patch release might be a better long-term solution.
Using * is generally considered a bad practice anyway though, not least because you're going to get a lot of duplicated columns from the joins (lots of dos_code_id in each row, for example); but you're also likely to be getting other data you don't really want, and anything that consumes this result set will have to assume the column order is always the same in those tables - any variation, or later addition or removal of a column, will cause problems.
What is wrong with the SQL statement? I get a message that there is a syntax error (missing operator). From the ASSIGNMENT TABLE I am wanting to select all rows where ASSN_TRANS_STATE_NUM = '1'. For each of these rows I then want to get the project name from the PROJECTS table. I also want to get each of the Task names from the TASKS table. I did get this to work earlier (not sure what change I made that broke it) but even when it did work it was not correct. It was reporting every task for each of the projects, instead of just giving me the tasks specific to a project.
SELECT
TRANS.PROJ_UID,
PROJ.PROJ_NAME,
TRANS.TASK_UID,
TASKS.TASK_NAME,
TRANS.ASSN_TRANS_STATE_ENUM,
TRANS.ASSN_TRANS_APPROVER_RES_UID
FROM dbo_MSP_ASSIGNMENT_TRANSACTIONS TRANS
INNER JOIN dbo_MSP_PROJECTS PROJ ON PROJ.PROJ_UID = TRANS.PROJ_UID
INNER JOIN dbo_MSP_TASKS TASKS ON TASKS.TASK_UID = TRANS.TASK_UID
WHERE TRANS.ASSN_TRANS_STATE_ENUM = 1;
It will be dbo. rather than dbo_. I guess it should help
SELECT
TRANS.PROJ_UID,
PROJ.PROJ_NAME,
TRANS.TASK_UID,
TASKS.TASK_NAME,
TRANS.ASSN_TRANS_STATE_ENUM,
TRANS.ASSN_TRANS_APPROVER_RES_UID
FROM dbo.MSP_ASSIGNMENT_TRANSACTIONS TRANS
INNER JOIN dbo.MSP_PROJECTS PROJ ON PROJ.PROJ_UID = TRANS.PROJ_UID
INNER JOIN dbo.MSP_TASKS TASKS ON TASKS.TASK_UID = TRANS.TASK_UID
WHERE TRANS.ASSN_TRANS_STATE_ENUM = 1;
I'm trying to get rid of left join fetch in one of our HQLs:
query = select r,f,c from ClassPos r, ClassFal f ,ClassCon c left join fetch c.ClassReg
where
DB contains this data satisfying above where clause:
ClassPos has 1 row, ClassFal has 2 rows, ClassCon has 1 row and ClassReg has 1 row.
We're using scrollable results to scroll through the results:
ScrollableResults results = query.scroll(ScrollMode.SCROLL_INSENSITIVE);
i =0
while(results.next())
{
i++
}
print(i);
We're expecting the resultset to have 2 rows but it's returning 1(i=1). When we run the SQL, we can clearly see 2 rows in the DB.
Now when we get rid of left join fetch, we see the result set has 2 rows:
query = select r,f,c from ClassPos r, ClassFal f ,ClassCon c
where <clause>
Tried looking up various places but can't get a reason. Can somebody explain this behaviour?
I am running the below SELECT statement to:
Return prices from a standard price list customer = 0
If the customer has been quoted a special price customer = X then use that price instead
I am getting the error message:
ERROR at line 3:
ORA-00933: SQL command not properly ended
Oracle version is: Oracle8i Enterprise Edition Release 8.1.7.4.0 - Production.
SELECT glas_daten_basis.idnr, glas_daten_basis.gl_bez, NVL(p2.zum2, p1.zum2)
FROM glas_daten_basis
JOIN os_przu p1 ON p1.idnr = glas_daten_basis.idnr
LEFT JOIN os_przu p2 ON p2.idnr = glas_daten_basis.idnr AND p2.kunr = 63
WHERE p1.kunr = 0;
Line 3 is the JOIN, is there something wrong here?
Update: There are 137 rows in the standard price list, so I should be given 137 rows regardless of whether the price is from customer = 0 or customer = X. The answers so far give me a ~60 rows for some reason.
SELECT os_przu.idnr, os_przu.zum2
FROM os_przu
WHERE os_przu.kunr = 0;
...
137 rows selected.
As #a_horse-with_no_name said, ANSI joins don't work in 8i; they weren't added until 9i. So if you're really stuck on this ancient and unsupported version you're stuck with the old Oracle-specific syntax:
SELECT glas_daten_basis.idnr, glas_daten_basis.gl_bez, NVL(p2.zum2, p1.zum2)
FROM glas_daten_basis, os_przu p1, os_przu p2
WHERE p1.idnr = glas_daten_basis.idnr
AND p1.kunr = 0
AND p2.idnr (+) = glas_daten_basis.idnr
AND p2.kunr (+) = 63;
Which is pretty similar to #nelucon's answer, except that only had one (+) left-join marker and it was on the wrong side of the condition.
SQL Fiddle.
The (+) is the Oracle-specific outer-join operator, and it has to be applied to each condition for the outer-joined table - if one is missed then the rest are ignored and it effectively becomes an inner join again. (One of the reasons ANSI joins are easier to work with, though you can still get that wrong by referring to the joined table in the where clause as well as the on.)
something like this, i didn't test the code but you got it. (+) means the left join. for more infos, google for "oracle 8 left join"
SELECT glas_daten_basis.idnr, glas_daten_basis.gl_bez, NVL(p2.zum2, p1.zum2)
FROM glas_daten_basis, os_przu p1, os_przu p2
WHERE p1.kunr = 0
AND p1.idnr = glas_daten_basis.idnr
AND p2.idnr = glas_daten_basis.idnr (+)
AND p2.kunr = 6;