PostgreSQL

0

Witam
Mam taki problem:
Jeśli poniższe zapytanie zwróci TRUE (lub wynik = 1):

select count(*) from
	(
		SELECT id_company , full_name , id_address , full_address , street , number , code , city , country FROM company_data WHERE ("nip" ='1111111111' OR "nip" = 'PL'||'1111111111')
	) as a
) = 1

To chciałbym, żeby wykonało się zapytanie:

SELECT id_company , full_name , id_address , full_address , street , number , code , city , country FROM company_data WHERE ("nip" ='1111111111' OR "nip" = 'PL'||'1111111111')

A gdy zwróci False lub liczbę różną od 1, to wykonało się zapytanie:

SELECT id_company , full_name , id_address , full_address , street , number , code , city , country FROM company_data WHERE (nip ='1111111111' OR nip = 'PL'||'1111111111') AND nrb='121323232312323232132132132'

Czy jest możliwe dokonanie tego w jakiś łatwy sposób?

1

Jeżeli dobrze rozumirm ideę, to można tak:

SELECT 
	id_company 
	,full_name 
	,id_address 
	,full_address 
	,street 
	,number 
	,code 
	,city 
	,country 
FROM 
	company_data 
WHERE 
	("nip" ='1111111111' OR "nip" = 'PL'||'1111111111')
ORDER BY
	CASE WHEN nrb='121323232312323232132132132' THEN 0 ELSE 1 END
LIMIT 
1
0

Do takich rzeczy warto skorzystać z procedur/funkcji składowanych.
W procedurach możesz używać ifów i podobnych konstrukcji.

Jeśli jest to rozwiązanie produkcyjne to powinno przyspieszyć pracę serwera.

0
Panczo napisał(a):

Jeżeli dobrze rozumirm ideę, to można tak:

SELECT 
	id_company 
	,full_name 
	,id_address 
	,full_address 
	,street 
	,number 
	,code 
	,city 
	,country 
FROM 
	company_data 
WHERE 
	("nip" ='1111111111' OR "nip" = 'PL'||'1111111111')
ORDER BY
	CASE WHEN nrb='121323232312323232132132132' THEN 0 ELSE 1 END
LIMIT 
1

No nie do końca. Chciałbym, żeby wynik pierwszego zapytania decydował, czy ma się wykonać drugie zapytanie, czy trzecie.

0
Maly Brat napisał(a):

Do takich rzeczy warto skorzystać z procedur/funkcji składowanych.
W procedurach możesz używać ifów i podobnych konstrukcji.

Jeśli jest to rozwiązanie produkcyjne to powinno przyspieszyć pracę serwera.

Próbowałem coś skleić, ale niestety nic mi nie zadziałało.

0

No nie do końca. Chciałbym, żeby wynik pierwszego zapytania decydował, czy ma się wykonać drugie zapytanie, czy trzecie.

Panczo podał dobrą propozycję. Czyli chcesz proste zapytanie skomplikować tak, żeby nikt czytając kod nie zrozumiał o co ci chodzi?
Może opisz jak to ma działać na początek bez używania SQL.

0
ralf napisał(a):

No nie do końca. Chciałbym, żeby wynik pierwszego zapytania decydował, czy ma się wykonać drugie zapytanie, czy trzecie.

Panczo podał dobrą propozycję. Czyli chcesz proste zapytanie skomplikować tak, żeby nikt czytając kod nie zrozumiał o co ci chodzi?
Może opisz jak to ma działać na początek bez używania SQL.

Ok, już wyjaśniam.

  1. Chcę wyszukać kontrahenta w bazie po NIP-ie.
  2. Jeżeli wyszukanie po NIP-ie zwróci mi więcej niż jeden wynik( może tak być, ponieważ kontrahenci dublują się ze względu na rożne numery rachunku bankowego), to chciałbym zawęzić wyszukiwanie i wyszukać kontrahenta po NIP-ie oraz Numerze Konta Bankowe.
  3. Nasuwa się pytanie dlaczego od razu nie wyszukać po NIP-ie i NRB. Dlatego, że nie zawsze otrzymuję drugi parametr do wyszukania którym jest NRB.

Podsumowując:

  1. Sprawdzam ile wyników wyników zwróci mi wyszukanie po NIP-ie.
  2. Jeżeli zwróciło mi jeden wynik to pobieram sobie te dane
  3. Jeśli sprawdzenie z pkt 1. zwróciło więcej niż jeden wynik, to wyszukuje kontrahenta po NIP-ie oraz NRB
1

Możesz użyć window functions oraz subquery do tego:

SELECT *
FROM (
  SELECT
    *,
    COUNT(*) OVER (PARTITION BY nip) AS duplicated 
  FROM clients) c
WHERE ("nip" ='1111111111' OR "nip" = 'PL'||'1111111111')
  AND (duplicated = 1 OR nrb = '121323232312323232132132132')

Przykład

2

Jeżeli wyszukanie po NIP-ie zwróci mi więcej niż jeden wynik( może tak być, ponieważ kontrahenci dublują się ze względu na rożne numery rachunku bankowego), to chciałbym zawęzić wyszukiwanie i wyszukać kontrahenta po NIP-ie oraz Numerze Konta Bankowe.

To jest błąd, jeżeli numery kont powielają kontrahenta to coś jest nie tak, pytanie czy powielenie wynika z joina, czy to faktycznie powielony rekord?

0
Panczo napisał(a):

Jeżeli wyszukanie po NIP-ie zwróci mi więcej niż jeden wynik( może tak być, ponieważ kontrahenci dublują się ze względu na rożne numery rachunku bankowego), to chciałbym zawęzić wyszukiwanie i wyszukać kontrahenta po NIP-ie oraz Numerze Konta Bankowe.

To jest błąd, jeżeli numery kont powielają kontrahenta to coś jest nie tak, pytanie czy powielenie wynika z joina, czy to faktycznie powielony rekord?

Z JOIN-a. jest osobna tabela na NRB.

0

No to jaki jest sens pytać o numer konta i go nie zwracać? W teorii dane powinny być takie same, wtedy limit załatwia sprawę

0
Panczo napisał(a):

No to jaki jest sens pytać o numer konta i go nie zwracać? W teorii dane powinny być takie same, wtedy limit załatwia sprawę

Chodzi o to, że nie zawsze dostaję drugi parametr, czyli NRB do wyszukiwania, Są sytuację kiedy otrzymuje tylko NIP a są sytuacje kiedy otrzymuje NIP i NRB.
I teraz biorąc pod uwagę, że są kontrahenci, do których przypisanych jest kilka NRB to:

  • gdy będę wyszukiwał tylko po NIP-ie, to jeśli zapytanie zwróci mi kilka wyników to nie będę wiedział którego użyć.
  • jeśli będę wyszukiwał po NIP-ie i NRB, a nie dostanę w parametrze NRB to zapytanie nic mi nie zwróci.
    W zdecydowanej większości przypadków jest tak, że dla kontrahenta który posiada tylko jeden NRB to dostaję tylko NIP, a dla kontrahenta z większą ilością NRB dostaję NIP i NRB.

Jestem w trakcie testów i wygląda na to, że zaproponowane wyżej przez kolegów rozwiązania sprawdzają się,

0

No nie do końca masz racje, możesz użyć alternatywy, do wykluczenia warunku, zakładając, że ktoś nie podał nipu, załóżmy że szablon zapytania wygląda tak:

SELECT 
	id_company , full_name , id_address , full_address , street , number , code , city , country FROM company_data 
WHERE 
	(nip ='@nip' OR nip = 'PL'||'@nip') 
	AND (nrb='@konto' or 'brak'='@konto')

Założenia:
Podmieniasz wartości zaczynające się od @, w razie braku @nrb wstawiasz brak, to zwróci wszystkie rokorfe dla brak, albo tylko pasujące dla zadanego nrb

`

1 użytkowników online, w tym zalogowanych: 0, gości: 1