Aktywne Wpisy
Kodzirasek +69
mirko_anonim +6
✨️ Obserwuj #mirkoanonim
#zwiazki #niebieskiepaski #rozowepaski
Czy 28-letnia kobieta ma szansę na zdrowy i fajny związek biorąc pod uwagę dzisiejszy rynek matrymonialny?
Jestem w długiej relacji już niemal 6 lat. Przez ten czas mimo obietnic nie doczekałam się ani pierścionka ani ślubu ani nawet poważniejszych wspólnych planów. Ciągle było realizowanie jego założeń, jego planów i marzeń a moje, no cóż... zostały gdzieś w tyle. Ale kochałam, chciałam wspierać i czekałam. Po kolejnej
#zwiazki #niebieskiepaski #rozowepaski
Czy 28-letnia kobieta ma szansę na zdrowy i fajny związek biorąc pod uwagę dzisiejszy rynek matrymonialny?
Jestem w długiej relacji już niemal 6 lat. Przez ten czas mimo obietnic nie doczekałam się ani pierścionka ani ślubu ani nawet poważniejszych wspólnych planów. Ciągle było realizowanie jego założeń, jego planów i marzeń a moje, no cóż... zostały gdzieś w tyle. Ale kochałam, chciałam wspierać i czekałam. Po kolejnej
Mam tabele w takiej postaci (nazwijmy ją "Tabela"):
A 1 0
A 2 1
A 3 1
A 4 0
A 5 0
B 1 0
B 2 0
B 3 0
B 4 1
Nazwę pierwszą kolumnę "Typem", drugą "Wartością", a trzecią "Flagą".
Moim zadaniem jest przetransformować tabele tak, że dla danego wiersza muszę odjąć od wartości tyle ile jest wierszy o tym samym typie, mniejszej wartości i fladze=1. Czyli wynikiem byłoby:
A 1
A 2
A 2 (-1, bo jeden wiersz "powyżej miał flage=1)
A 2 (-2, bo dwa wiersze "powyżej" miały flage=1)
A 3 (-2, bo dwa wiersze "powyżej" miały flage=1)
B 1
B 2
B 3
B 4
Użyłem słowa "powyżej", bo w tym przykładzie faktycznie są one powyżej dla łatwiejszego zobrazowania problemu.
Chciałbym to zrobić jak najbardziej możliwie optymalnie pod względem czasu. Aktualnie od drugiej kolumny odejmuje coś takiego i jest zdecydowanie za wolne:
Coalesce(SUM(CASE WHEN Flaga = 1 THEN 1 ELSE 0 END) OVER
(PARTITION BY Typ ORDER BY Wartość
ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING), 0)
Próbowałem też odjąć:
SELECT COUNT(*) FROM temp where temp.Typ = Tabela.Typ and temp.Wartość < Tabela.Wartość and Tabela.Flaga = 1
ale to było jeszcze wolniejsze xD
Może wy będziecie mieli jakieś lepsze pomysły.
with
x as (
select type, value
from test
where flag=1
)
,y as (
select t.*
from test t
cross join x
where
t.type=x.type
and t.value>x.value
)
,z as (
select
count(*) AS subtract
,type
,value
from
y
group BY
type
,value
)
SELECT
t.*
,z.subtract
FROM
test t
LEFT JOIN
z ON z.type=t.type AND t.value=z.value
edit: wykop
SELECT
*,
Wartosc - SUM(Flaga) OVER (PARTITION BY Typ ORDER BY Wartosc ROWS UNBOUNDED PRECEDING) as Wynik
FROM
Tabela
Chyba najszybsze, jak Flaga jest typu Bit/Boolean to możliwe że musisz ją w tej sumie konwertować na int
A jak chcesz jeszcze bardziej przyspieszyć to index stworzony w ramach reguły POC (Partition, Ordering, Covering):
CREATE NONCLUSTERED INDEX IX_void ON Tabela(Typ, Wartosc) INCLUDE (Flaga)
Składnia pod MS SQL
W ogóle, jaka baza?
Tworzysz tabelę tymczasową z jedną kolumną, wrzucasz tam jedną wartość (np. kolumna Dupa i wartość INT = 1) i... Zakładasz na niej CLUSTERED COLUMNSTORE INDEX
Potem robisz CROSS APPLY do swojej tabeli w zapytaniu i jest opcja, że wtedy wymusisz na silniku użycie Batch Mode zamiast